#!/usr/bin/env python2.3

"""
wxToolBar_DEMO.py - Toolbar generation using embedded images.
WorkingWithToolBars @ http ://wiki.wxpython.org/WorkingWithToolBars
Chris.Barker@noaa.gov     200?

Updated and modified by Ray Pasco   2011-04-24
pascor@verion.net


# Note: I use python2.3 above because my system has 2.2, 2.1, and 1.5.2 installed also

This is demo of a number of things that can be done with toolbars. 
When run from a console, it writes messages to indicate toolbar button events.

This includes :
- Having it managed by a Frame : the most basic way of creating a toolbar

- Placing a toolbar in a wxPanel with a sizer so that you can have a
  custom panel with a toolbar attached, rather than a frame

- Placing multiple toolbars in a Panel. This could be done inside a frame, instead.

- Using a wxStaticBitmap on a toolbar : Use custom separator (one that's visible) 
  Do this if you don't like the one that comes with the stock widget, 
  or want the same look on all platforms.

- Making a set of buttons on a toolbar act like radio buttons : That is, 
  only one is shown to be pressed at a time.

A few things in the demo that are not strictly about toolbars :

- Multiple panels, each with its own toolbar.

- Uses code generated by the old version of img2py.py to embed icons into Python code.

"""

import wx

# It's easiest to generate & manage embedded graphics data when it's in a single separate file.
import EmbeddedIconData as eid     

#------------------------------------------------------------------------------

ID_ZOOM_IN_BUTTON       = wx.NewId()
ID_ZOOM_OUT_BUTTON      = wx.NewId()
ID_TEST_BUTTON          = wx.NewId()
ID_MOVE_MODE_BUTTON     = wx.NewId()

ID_ZOOM_IN_BUTTON2      = wx.NewId()
ID_ZOOM_OUT_BUTTON2     = wx.NewId()
ID_TEST_BUTTON2         = wx.NewId()
ID_MOVE_MODE_BUTTON2    = wx.NewId()

ID_TOOLBAR = wx.NewId()

#------------------------------------------------------------------------------

class TestPanel( wx.Panel ) :
    """
    A Panel class with one or two attached toolbars.
    """

    def __init__( self, parent, id=wx.ID_ANY, size=wx.DefaultSize, color="BLUE", numToolbars=1 ) :

        wx.Panel.__init__( self, parent, id, wx.Point( 0, 0 ), size, wx.SUNKEN_BORDER )
        self.WindowColor = color

        ## Create the vertical sizer for the toolbar and Panel
        box = wx.BoxSizer( wx.VERTICAL )
        tb = self.BuildToolbar1()
        box.Add( tb, 0, wx.ALL | wx.ALIGN_LEFT | wx.EXPAND, 4 ) # add the toolbar to the sizer
        
        if numToolbars == 2 : # Do we want the second toolbar?
            tb = self.BuildToolbar2()
            box.Add( tb, 0, wx.ALL | wx.ALIGN_RIGHT , 4 )# This one gets aligned to the right

        #Now add a Window to draw stuff to ( this could be any wx.Window derived control ) 
        self.DrawWindow = wx.Window( self, -1, wx.DefaultPosition, wx.DefaultSize, wx.SUNKEN_BORDER )
        box.Add( self.DrawWindow, 1, wx.EXPAND )

        box.Fit( self )
        self.SetAutoLayout( True )
        self.SetSizer( box )

        # this connects the OnPaint handler to when the DrawWindow needs to be re-painted
        wx.EVT_PAINT( self.DrawWindow, self.OnPaint )
    
    #end __init__
    
    #-----
    
    def BuildToolbar1( self ) :

        """
        creates one of the toolbars

        The buttons act like radio buttons, setting a mode for the Panel
        Only one of them is pressed at a time. The SetMode() method handles this

        """
        
        tb = wx.ToolBar( self, -1 )
        self.ToolBar = tb
        tb.SetToolBitmapSize( ( 21, 21 ) )# this required for non-standard size buttons on MSW
        
        tb.AddTool( ID_ZOOM_IN_BUTTON, eid.GetPlusBitmap(), isToggle=True )
        wx.EVT_TOOL( self, ID_ZOOM_IN_BUTTON, self.SetMode )
        
        tb.AddTool( ID_ZOOM_OUT_BUTTON, eid.GetMinusBitmap(), isToggle=True )
        wx.EVT_TOOL( self, ID_ZOOM_OUT_BUTTON, self.SetMode )
        
        tb.AddTool( ID_MOVE_MODE_BUTTON, eid.GetHandBitmap(), isToggle=True )
        wx.EVT_TOOL( self, ID_MOVE_MODE_BUTTON, self.SetMode )
        
        tb.AddSeparator()   # Invisible spacer
        
        # A way to insert a custom separator.
        tb.AddControl( wx.StaticBitmap( tb, wx.ID_ANY, eid.GetSeparatorBitmap() ) )
        
        tb.AddSeparator()   # Invisible spacer
        
        tb.AddControl( wx.Button( tb, ID_TEST_BUTTON, "Button", wx.DefaultPosition, wx.DefaultSize ) )
        wx.EVT_BUTTON( self, ID_TEST_BUTTON, self.ButtonAction )
        
        tb.Realize()
        
        return tb
        
    #end BuildToolbar1 def
    
    #-----
    
    def BuildToolbar2( self ) :

        """
        Creates another toolbar. It looks the same, but acts a little different :
        The buttons are independent, rather than acting like radio buttons

        It also has a custom separator, created by adding a tall skinny bitmap.
        """
        
        tb = wx.ToolBar( self, id=wx.ID_ANY )
        self.ToolBar2 = tb
        tb.SetToolBitmapSize( (21, 21) ) # Square spacer equired for non-standard size buttons on MSW
        
        tb.AddTool( ID_ZOOM_IN_BUTTON2, eid.GetPlusBitmap(), isToggle=True )
        wx.EVT_TOOL( self, ID_ZOOM_IN_BUTTON2, self.ButtonPress2 )
        
        tb.AddTool( ID_ZOOM_OUT_BUTTON2, eid.GetMinusBitmap(), isToggle=True )
        wx.EVT_TOOL( self, ID_ZOOM_OUT_BUTTON2, self.ButtonPress2 )
        
        tb.AddTool( ID_MOVE_MODE_BUTTON2, eid.GetHandBitmap(), isToggle=True )
        wx.EVT_TOOL( self, ID_MOVE_MODE_BUTTON2, self.ButtonPress2 )
        
        tb.AddSeparator()   # Invisible spacer
        
        # A way to insert a custom separator.
        tb.AddControl( wx.StaticBitmap( tb, wx.ID_ANY, eid.GetSeparatorBitmap() ) )
        
        tb.AddSeparator()   # Invisible spacer
        
        tb.AddControl( wx.Button( tb, ID_TEST_BUTTON2, "Button", wx.DefaultPosition, wx.DefaultSize ) )
        wx.EVT_BUTTON( self, ID_TEST_BUTTON2, self.ButtonPress2 )
        
        tb.Realize()
        
        return tb
        
    #end BuildToolbar2 def
    
    #-----
    
    def ButtonPress2( self, event ) :
        print "%s Panel second toolbar button clicked" % self.WindowColor

    def SetMode( self, event ) :
        
        # Deselect all the buttons.
        for id in [ID_ZOOM_IN_BUTTON, ID_ZOOM_OUT_BUTTON, ID_MOVE_MODE_BUTTON] :
            self.ToolBar.ToggleTool( id, 0 )
        
        # Select this button.
        self.ToolBar.ToggleTool( event.GetId(), 1 )
        if event.GetId() == ID_ZOOM_IN_BUTTON :
            print "Mode set to Zoom In in the %s Canvas" % self.WindowColor
        
        elif event.GetId() == ID_ZOOM_OUT_BUTTON :
            print "Mode set to Zoom Out in the %s Canvas" % self.WindowColor
        
        elif event.GetId() == ID_MOVE_MODE_BUTTON :
            print "Mode set to Move in the %s Canvas" % self.WindowColor

    def ButtonAction( self, event ) :
        print "%s Canvas button clicked" % self.WindowColor
        pass

    def OnPaint( self, event ) :
        dc = wx.PaintDC( self.DrawWindow )
        dc.SetBackground( wx.Brush( wx.NamedColour( self.WindowColor ) ) )
        dc.BeginDrawing()
        dc.Clear()
        dc.EndDrawing()

#end TestPanel class

#------------------------------------------------------------------------------

class TestFrame( wx.Frame ) :
    
    def __init__( self, parent=None, id=wx.ID_ANY, title='Default Title', 
                  pos=wx.DefaultPosition, size=( 600, 500 )  ) :
        
        wx.Frame.__init__( self, parent, id, title, pos, size )
        
        wx.EVT_CLOSE( self, self.OnCloseWindow )
        
        #-----
        
        Canvas1 = TestPanel( self, color = "RED" )
        Canvas2 = TestPanel( self, color = "BLUE", numToolbars = 2 )
        
        #Build the Toolbar
        tb = self.CreateToolBar( wx.TB_HORIZONTAL|wx.NO_BORDER )
        self.ToolBar = tb
        tb.SetToolBitmapSize( ( 21, 21 ) )# this required for non-standard size buttons on MSW

        tb.AddTool( ID_ZOOM_IN_BUTTON, eid.GetPlusBitmap(), isToggle=True )
        wx.EVT_TOOL( self, ID_ZOOM_IN_BUTTON, self.SetMode )

        tb.AddTool( ID_ZOOM_OUT_BUTTON, eid.GetMinusBitmap(), isToggle=True )
        wx.EVT_TOOL( self, ID_ZOOM_OUT_BUTTON, self.SetMode )

        tb.AddTool( ID_MOVE_MODE_BUTTON, eid.GetHandBitmap(), isToggle=True )
        wx.EVT_TOOL( self, ID_MOVE_MODE_BUTTON, self.SetMode )

        tb.AddSeparator()   # Invisible spacer
        
        tb.AddControl( wx.Button( tb, ID_TEST_BUTTON, "Button", wx.DefaultPosition, wx.DefaultSize ) )
        wx.EVT_BUTTON( self, ID_TEST_BUTTON, self.ButtonAction )

        tb.AddSeparator()   # Invisible spacer
        
        # A way to insert a custom separator.
        tb.AddControl( wx.StaticBitmap( tb, wx.ID_ANY, eid.GetSeparatorBitmap() ) )
        
        tb.AddSeparator()   # Invisible spacer
        
        msg = 'A Frame-Managed Toolbar - Try Resizing the Frame Horizontally !'
        tb.AddControl( wx.StaticText( tb, -1, msg ) )

        tb.Realize()
        
        ## Create the horizontal sizer for the two panels
        box = wx.BoxSizer( wx.HORIZONTAL )

        box.Add( Canvas1 , 1, wx.EXPAND )
        box.Add( Canvas2 , 2, wx.EXPAND )

        box.Fit( self )
        #self.SetAutoLayout()
        self.SetSizer( box )
        
        self.Show()
        
    #end __init__

    def SetMode( self, event ) :
        
        # Deselect all the buttons.
        for id in [ID_ZOOM_IN_BUTTON, ID_ZOOM_OUT_BUTTON, ID_MOVE_MODE_BUTTON] :
            self.ToolBar.ToggleTool( id, 0 )
        
        # Select this button.
        self.ToolBar.ToggleTool( event.GetId(), 1 )
        if event.GetId() == ID_ZOOM_IN_BUTTON :
            print "Mode set to Zoom In in the Frame"
        
        elif event.GetId() == ID_ZOOM_OUT_BUTTON :
            print "Mode set to Zoom Out in the Frame"
        
        elif event.GetId() == ID_MOVE_MODE_BUTTON :
            print "Mode set to Move in the Frame"

    def ButtonAction( self, event ) :
        print "Button clicked in the Frame"
        pass

    def OnCloseWindow( self, event ) :
        self.Destroy()

#end TestFrame class

#==============================================================================

if __name__ == "__main__" :
    
    app = wx.App( redirect=False )
    
    appFrame = TestFrame(  None, wx.ID_ANY, "Embedded Graphics Toolbar Test", 
                          pos=( 100, 100 ), size=( 550, 200 ) )
    #app.SetTopWindow( appFrame )
    
    app.MainLoop()

#end if
