andrej@1574: # --------------------------------------------------------------------------- #
andrej@1574: # ENHANCEDSTATUSBAR wxPython IMPLEMENTATION
andrej@1574: # Python Code By:
andrej@1574: #
andrej@1574: # Andrea Gavana, @ 31 May 2005
andrej@1574: # Nitro, @ 21 September 2005
andrej@1574: # Latest Revision: 21 September 2005, 19.57.20 GMT+2
andrej@1574: # Latest Revision before Latest Revision: 21 September 2005, 18.29.35 GMT+2
andrej@1574: # Latest Revision before Latest Revision before Latest Revision: 31 May 2005, 23.17 CET
andrej@1574: #
andrej@1574: #
andrej@1574: # TODO List/Caveats
andrej@1574: #
andrej@1574: # 1. Some Requests/Features To Add?
andrej@1574: #
andrej@1574: #
andrej@1574: # For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
andrej@1574: # Write To Me At:
andrej@1574: # 
andrej@1574: #
andrej@1574: # andrea.gavana@agip.it
andrej@1574: # andrea_gavan@tin.it
andrej@1574: #
andrej@1574: # Or, Obviously, To The wxPython Mailing List!!!
andrej@1574: #
andrej@1574: #
andrej@1574: # licensed under wxWidgets License (GPL compatible)
andrej@1574: # End Of Comments
andrej@1574: # --------------------------------------------------------------------------- #
andrej@1574: 
andrej@1574: """ Description:
andrej@1574: 
andrej@1574: EnhancedStatusBar Is A Slight Modification (Actually A Subclassing) Of wx.StatusBar.
andrej@1574: It Allows You To Add Almost Any Widget You Like To The wx.StatusBar Of Your Main
andrej@1574: Frame Application And Also To Layout Them Properly.
andrej@1574: 
andrej@1574: 
andrej@1574: What It Can Do:
andrej@1574: 
andrej@1574: 1) Almost All The Functionalities Of wx.StatusBar Are Still Present;
andrej@1574: 2) You Can Add Different Kind Of Widgets Into Every Field Of The EnhancedStatusBar;
andrej@1574: 3) The AddWidget() Methods Accepts 2 Layout Inputs:
andrej@1574:    - horizontalalignment: This Specify The Horizontal Alignment For Your Widget,
andrej@1574:      And Can Be ESB_EXACT_FIT, ESB_ALIGN_CENTER_HORIZONTAL, ESB_ALIGN_LEFT And
andrej@1574:      ESB_ALIGN_RIGHT;
andrej@1574:    - varticalalignment: This Specify The Vertical Alignment For Your Widget,
andrej@1574:      And Can Be ESB_EXACT_FIT, ESB_ALIGN_CENTER_VERTICAL, ESB_ALIGN_BOTTOM And
andrej@1574:      ESB_ALIGN_LEFT;
andrej@1574: 
andrej@1574: EnhancedStatusBar Is Freeware And Distributed Under The wxPython License. 
andrej@1574: 
andrej@1574: Latest Revision: 21 September 2005, 19.57.20 GMT+2
andrej@1574: Latest Revision before Latest Revision: 21 September 2005, 18.29.35 GMT+2
andrej@1574: Latest Revision before Latest Revision before Latest Revision: 31 May 2005, 23.17 CET
andrej@1574: 
andrej@1574: """
andrej@1574: 
andrej@1574: import wx
andrej@1574: 
andrej@1574: # Horizontal Alignment Constants
andrej@1574: ESB_ALIGN_CENTER_VERTICAL = 1
andrej@1574: ESB_ALIGN_TOP = 2
andrej@1574: ESB_ALIGN_BOTTOM = 3
andrej@1574: 
andrej@1574: # Vertical Alignment Constants
andrej@1574: ESB_ALIGN_CENTER_HORIZONTAL = 11
andrej@1574: ESB_ALIGN_LEFT = 12
andrej@1574: ESB_ALIGN_RIGHT = 13
andrej@1574: 
andrej@1574: # Exact Fit (Either Horizontal Or Vertical Or Both) Constant
andrej@1574: ESB_EXACT_FIT = 20
andrej@1574: 
andrej@1574: 
andrej@1574: # ---------------------------------------------------------------
andrej@1574: # Class EnhancedStatusBar
andrej@1574: # ---------------------------------------------------------------
andrej@1574: # This Is The Main Class Implementation. See The Demo For Details
andrej@1574: # ---------------------------------------------------------------
andrej@1574: class EnhancedStatusBarItem(object):
andrej@1574:     def __init__(self, widget, pos, horizontalalignment=ESB_ALIGN_CENTER_HORIZONTAL, verticalalignment=ESB_ALIGN_CENTER_VERTICAL):
andrej@1574:         self.__dict__.update( locals() )
andrej@1574: 
andrej@1574: class EnhancedStatusBar(wx.StatusBar):
andrej@1574: 
andrej@1574:     def __init__(self, parent, id=wx.ID_ANY, style=wx.ST_SIZEGRIP,
andrej@1574:                  name="EnhancedStatusBar"):
andrej@1574:         """Default Class Constructor.
andrej@1574: 
andrej@1574:         EnhancedStatusBar.__init__(self, parent, id=wx.ID_ANY,
andrej@1574:                                    style=wx.ST_SIZEGRIP,
andrej@1574:                                    name="EnhancedStatusBar")
andrej@1574:         """
andrej@1574:         
andrej@1574:         wx.StatusBar.__init__(self, parent, id, style, name)
andrej@1574:         
andrej@1574:         self._items = {}
andrej@1574:         self._curPos = 0
andrej@1574:         self._parent = parent
andrej@1574:         
andrej@1574:         wx.EVT_SIZE(self, self.OnSize) 
andrej@1574:         wx.CallAfter(self.OnSize, None)
andrej@1574: 
andrej@1574:             
andrej@1574:     def OnSize(self, event):
andrej@1574:         """Handles The wx.EVT_SIZE Events For The StatusBar.
andrej@1574: 
andrej@1574:         Actually, All The Calculations Linked To HorizontalAlignment And
andrej@1574:         VerticalAlignment Are Done In This Function."""
andrej@1574: 
andrej@1574:         for pos, item in self._items.items():
andrej@1574:             widget, horizontalalignment, verticalalignment = item.widget, item.horizontalalignment, item.verticalalignment
andrej@1574:            
andrej@1574:             rect = self.GetFieldRect(pos)
andrej@1574:             widgetpos = widget.GetPosition()
andrej@1574:             widgetsize = widget.GetSize()
andrej@1574: 
andrej@1574:             rect = self.GetFieldRect(pos)
andrej@1574:             
andrej@1574:             if horizontalalignment == ESB_EXACT_FIT:
andrej@1574:                 
andrej@1574:                 if verticalalignment == ESB_EXACT_FIT:
andrej@1574:                     """ 1 September 2015 Fix fit align """
andrej@1574:                     widget.SetSize((rect.width-4, rect.height-4))
andrej@1574:                     widget.SetPosition((rect.x+2, rect.y+2))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_CENTER_VERTICAL:
andrej@1574:                     if widgetsize[1] < rect.width - 1:
andrej@1574:                         diffs = (rect.height - widgetsize[1])/2
andrej@1574:                         widget.SetSize((rect.width-2, widgetsize[1]))
andrej@1574:                         widget.SetPosition((rect.x-1, rect.y+diffs))
andrej@1574:                     else:
andrej@1574:                         widget.SetSize((rect.width-2, widgetsize[1]))
andrej@1574:                         widget.SetPosition((rect.x-1, rect.y-1))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_TOP:
andrej@1574:                     widget.SetSize((rect.width-2, widgetsize[1]))
andrej@1574:                     widget.SetPosition((rect.x-1, rect.y))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_BOTTOM:
andrej@1574:                     widget.SetSize((rect.width-2, widgetsize[1]))
andrej@1574:                     widget.SetPosition((rect.x-1, rect.height-widgetsize[1]))
andrej@1574: 
andrej@1574:             elif horizontalalignment == ESB_ALIGN_LEFT:
andrej@1574:                 
andrej@1574:                 xpos = rect.x - 1
andrej@1574:                 if verticalalignment == ESB_EXACT_FIT:
andrej@1574:                     widget.SetSize((widgetsize[0], rect.height-2))
andrej@1574:                     widget.SetPosition((xpos, rect.y-1))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_CENTER_VERTICAL:
andrej@1574:                     if widgetsize[1] < rect.height - 1:
andrej@1574:                         diffs = (rect.height - widgetsize[1])/2
andrej@1574:                         widget.SetPosition((xpos, rect.y+diffs))
andrej@1574:                     else:
andrej@1574:                         widget.SetSize((widgetsize[0], rect.height-2))
andrej@1574:                         widget.SetPosition((xpos, rect.y-1))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_TOP:
andrej@1574:                     widget.SetPosition((xpos, rect.y))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_BOTTOM:
andrej@1574:                     widget.SetPosition((xpos, rect.height-widgetsize[1]))
andrej@1574:                 
andrej@1574:             elif horizontalalignment == ESB_ALIGN_RIGHT:
andrej@1574:                 
andrej@1574:                 xpos = rect.x + rect.width - widgetsize[0] - 1
andrej@1574:                 if verticalalignment == ESB_EXACT_FIT:
andrej@1574:                     widget.SetSize((widgetsize[0], rect.height-2))
andrej@1574:                     widget.SetPosition((xpos, rect.y-1))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_CENTER_VERTICAL:
andrej@1574:                     if widgetsize[1] < rect.height - 1:
andrej@1574:                         diffs = (rect.height - widgetsize[1])/2
andrej@1574:                         widget.SetPosition((xpos, rect.y+diffs))
andrej@1574:                     else:
andrej@1574:                         widget.SetSize((widgetsize[0], rect.height-2))
andrej@1574:                         widget.SetPosition((xpos, rect.y-1))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_TOP:
andrej@1574:                     widget.SetPosition((xpos, rect.y))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_BOTTOM:
andrej@1574:                     widget.SetPosition((xpos, rect.height-widgetsize[1]))
andrej@1574: 
andrej@1574:             elif horizontalalignment == ESB_ALIGN_CENTER_HORIZONTAL:
andrej@1574:                 
andrej@1574:                 xpos = rect.x + (rect.width - widgetsize[0])/2 - 1
andrej@1574:                 if verticalalignment == ESB_EXACT_FIT:
andrej@1574:                     widget.SetSize((widgetsize[0], rect.height))
andrej@1574:                     widget.SetPosition((xpos, rect.y))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_CENTER_VERTICAL:
andrej@1574:                     if widgetsize[1] < rect.height - 1:
andrej@1574:                         diffs = (rect.height - widgetsize[1])/2
andrej@1574:                         widget.SetPosition((xpos, rect.y+diffs))
andrej@1574:                     else:
andrej@1574:                         widget.SetSize((widgetsize[0], rect.height-1))
andrej@1574:                         widget.SetPosition((xpos, rect.y+1))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_TOP:
andrej@1574:                     widget.SetPosition((xpos, rect.y))
andrej@1574:                 elif verticalalignment == ESB_ALIGN_BOTTOM:
andrej@1574:                     widget.SetPosition((xpos, rect.height-widgetsize[1]))
andrej@1574: 
andrej@1574:                 
andrej@1574:         if event is not None:
andrej@1574:             event.Skip()
andrej@1574:         
andrej@1574:         
andrej@1574:     def AddWidget(self, widget, horizontalalignment=ESB_ALIGN_CENTER_HORIZONTAL,
andrej@1574:                   verticalalignment=ESB_ALIGN_CENTER_VERTICAL, pos = -1):
andrej@1574:         """Add A Widget To The EnhancedStatusBar.
andrej@1574: 
andrej@1574:         Parameters:
andrej@1574: 
andrej@1574:         - horizontalalignment: This Can Be One Of:
andrej@1574:           a) ESB_EXACT_FIT: The Widget Will Fit Horizontally The StatusBar Field Width;
andrej@1574:           b) ESB_ALIGN_CENTER_HORIZONTAL: The Widget Will Be Centered Horizontally In
andrej@1574:              The StatusBar Field;
andrej@1574:           c) ESB_ALIGN_LEFT: The Widget Will Be Left Aligned In The StatusBar Field;
andrej@1574:           d) ESB_ALIGN_RIGHT: The Widget Will Be Right Aligned In The StatusBar Field;
andrej@1574: 
andrej@1574:         - verticalalignment:
andrej@1574:           a) ESB_EXACT_FIT: The Widget Will Fit Vertically The StatusBar Field Height;
andrej@1574:           b) ESB_ALIGN_CENTER_VERTICAL: The Widget Will Be Centered Vertically In
andrej@1574:              The StatusBar Field;
andrej@1574:           c) ESB_ALIGN_BOTTOM: The Widget Will Be Bottom Aligned In The StatusBar Field;
andrej@1574:           d) ESB_ALIGN_TOP: The Widget Will Be TOP Aligned In The StatusBar Field;
andrej@1574: 
andrej@1574:         """
andrej@1574: 
andrej@1574:         if pos == -1:
andrej@1574:             pos = self._curPos
andrej@1574:             self._curPos += 1
andrej@1574:         
andrej@1574:         if self.GetFieldsCount() <= pos:
andrej@1574:             raise "\nERROR: EnhancedStatusBar has a max of %d items, you tried to set item #%d" % (self.GetFieldsCount(), pos)
andrej@1574: 
andrej@1574:         if horizontalalignment not in [ESB_ALIGN_CENTER_HORIZONTAL, ESB_EXACT_FIT,
andrej@1574:                                        ESB_ALIGN_LEFT, ESB_ALIGN_RIGHT]:
andrej@1574:             raise '\nERROR: Parameter "horizontalalignment" Should Be One Of '\
andrej@1574:                   '"ESB_ALIGN_CENTER_HORIZONTAL", "ESB_ALIGN_LEFT", "ESB_ALIGN_RIGHT"' \
andrej@1574:                   '"ESB_EXACT_FIT"'
andrej@1574: 
andrej@1574:         if verticalalignment not in [ESB_ALIGN_CENTER_VERTICAL, ESB_EXACT_FIT,
andrej@1574:                                      ESB_ALIGN_TOP, ESB_ALIGN_BOTTOM]:
andrej@1574:             raise '\nERROR: Parameter "verticalalignment" Should Be One Of '\
andrej@1574:                   '"ESB_ALIGN_CENTER_VERTICAL", "ESB_ALIGN_TOP", "ESB_ALIGN_BOTTOM"' \
andrej@1574:                   '"ESB_EXACT_FIT"'
andrej@1574:         
andrej@1574: 
andrej@1574:         try:
andrej@1574:             self.RemoveChild(self._items[pos].widget)
andrej@1574:             self._items[pos].widget.Destroy()
andrej@1574:         except KeyError: pass
andrej@1574:         
andrej@1574:         self._items[pos] = EnhancedStatusBarItem(widget, pos, horizontalalignment, verticalalignment)
andrej@1574:         
andrej@1574:         wx.CallAfter(self.OnSize, None)