]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/lib/flatnotebook.py
Compile fixes for Panther
[wxWidgets.git] / wxPython / wx / lib / flatnotebook.py
index fc3199867c22e5f65d938de0e989ed51d5dcf81f..309214c282d0ffdeeb72d978fb50cc06d7d9dc99 100644 (file)
@@ -11,7 +11,7 @@
 # Python Code By:
 #
 # Andrea Gavana, @ 02 Oct 2006
 # Python Code By:
 #
 # Andrea Gavana, @ 02 Oct 2006
-# Latest Revision: 10 Oct 2006, 21.00 GMT
+# Latest Revision: 12 Oct 2006, 20.00 GMT
 #
 #
 # For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
 #
 #
 # For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
@@ -58,7 +58,7 @@ License And Version:
 
 FlatNotebook Is Freeware And Distributed Under The wxPython License. 
 
 
 FlatNotebook Is Freeware And Distributed Under The wxPython License. 
 
-Latest Revision: Andrea Gavana @ 10 Oct 2006, 21.00 GMT
+Latest Revision: Andrea Gavana @ 12 Oct 2006, 20.00 GMT
 
 Version 2.0.
 
 
 Version 2.0.
 
@@ -79,7 +79,7 @@ import random
 import math
 import weakref
 import cPickle
 import math
 import weakref
 import cPickle
-
+    
 # Check for the new method in 2.7 (not present in 2.6.3.3)
 if wx.VERSION_STRING < "2.7":
     wx.Rect.Contains = lambda self, point: wx.Rect.Inside(self, point)
 # Check for the new method in 2.7 (not present in 2.6.3.3)
 if wx.VERSION_STRING < "2.7":
     wx.Rect.Contains = lambda self, point: wx.Rect.Inside(self, point)
@@ -146,6 +146,9 @@ FNB_DROPDOWN_TABS_LIST = 16384
 FNB_ALLOW_FOREIGN_DND = 32768
 """Allows drag 'n' drop operations between different L{FlatNotebook}s"""
 
 FNB_ALLOW_FOREIGN_DND = 32768
 """Allows drag 'n' drop operations between different L{FlatNotebook}s"""
 
+FNB_HIDE_ON_SINGLE_TAB = 65536
+"""Hides the Page Container when there is one or fewer tabs"""
+
 VERTICAL_BORDER_PADDING = 4
 
 # Button size is a 16x16 xpm bitmap
 VERTICAL_BORDER_PADDING = 4
 
 # Button size is a 16x16 xpm bitmap
@@ -181,7 +184,7 @@ FNB_DROP_DOWN_ARROW = 6 # On the drop down arrow button
 FNB_NOWHERE = 0         # Anywhere else
 """Indicates mouse coordinates not on any tab of the notebook"""
 
 FNB_NOWHERE = 0         # Anywhere else
 """Indicates mouse coordinates not on any tab of the notebook"""
 
-FNB_DEFAULT_STYLE = FNB_MOUSE_MIDDLE_CLOSES_TABS
+FNB_DEFAULT_STYLE = FNB_MOUSE_MIDDLE_CLOSES_TABS | FNB_HIDE_ON_SINGLE_TAB
 """L{FlatNotebook} default style"""
 
 # FlatNotebook Events:
 """L{FlatNotebook} default style"""
 
 # FlatNotebook Events:
@@ -713,6 +716,31 @@ def PaintStraightGradientBox(dc, rect, startColor, endColor, vertical=True):
     dc.SetBrush(savedBrush)
 
 
     dc.SetBrush(savedBrush)
 
 
+# ---------------------------------------------------------------------------- #
+# Class FNBDropSource
+# Gives Some Custom UI Feedback during the DnD Operations
+# ---------------------------------------------------------------------------- #
+
+class FNBDropSource(wx.DropSource):
+    """
+    Give some custom UI feedback during the drag and drop operation in this
+    function. It is called on each mouse move, so your implementation must
+    not be too slow.
+    """
+    
+    def __init__(self, win):
+        """ Default class constructor. Used internally. """
+        
+        wx.DropSource.__init__(self, win)
+        self._win = win
+
+
+    def GiveFeedback(self, effect):
+        """ Provides user with a nice feedback when tab is being dragged. """
+
+        self._win.DrawDragHint()
+        return False
+
 
 # ---------------------------------------------------------------------------- #
 # Class FNBDragInfo
 
 # ---------------------------------------------------------------------------- #
 # Class FNBDragInfo
@@ -1129,7 +1157,7 @@ class TabNavigatorWindow(wx.Dialog):
         bk = self.GetParent()
         self._selectedItem = self._listBox.GetSelection()
         iter = self._indexMap[self._selectedItem]
         bk = self.GetParent()
         self._selectedItem = self._listBox.GetSelection()
         iter = self._indexMap[self._selectedItem]
-        bk.SetSelection(iter)
+        bk._pages.FireEvent(iter)
         self.EndModal(wx.ID_OK)
         
 
         self.EndModal(wx.ID_OK)
         
 
@@ -1194,6 +1222,7 @@ class FNBRenderer:
         self._xBgBmp = wx.EmptyBitmap(16, 14)
         self._leftBgBmp = wx.EmptyBitmap(16, 14)
         self._rightBgBmp = wx.EmptyBitmap(16, 14)
         self._xBgBmp = wx.EmptyBitmap(16, 14)
         self._leftBgBmp = wx.EmptyBitmap(16, 14)
         self._rightBgBmp = wx.EmptyBitmap(16, 14)
+        self._tabHeight = None
 
 
     def GetLeftButtonPos(self, pageContainer):
 
 
     def GetLeftButtonPos(self, pageContainer):
@@ -1549,6 +1578,9 @@ class FNBRenderer:
     def CalcTabHeight(self, pageContainer):
         """ Calculates the height of the input tab. """
 
     def CalcTabHeight(self, pageContainer):
         """ Calculates the height of the input tab. """
 
+        if self._tabHeight:
+            return self._tabHeight
+
         pc = pageContainer
         dc = wx.MemoryDC()
         dc.SelectObject(wx.EmptyBitmap(1,1))
         pc = pageContainer
         dc = wx.MemoryDC()
         dc.SelectObject(wx.EmptyBitmap(1,1))
@@ -1558,8 +1590,10 @@ class FNBRenderer:
         # on MSW, preforming these steps yields wierd results
         normalFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
         boldFont = normalFont
         # on MSW, preforming these steps yields wierd results
         normalFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
         boldFont = normalFont
-        boldFont.SetWeight(wx.FONTWEIGHT_BOLD)
-        dc.SetFont(boldFont)
+
+        if "__WXGTK__" in wx.PlatformInfo:
+            boldFont.SetWeight(wx.FONTWEIGHT_BOLD)
+            dc.SetFont(boldFont)
 
         height = dc.GetCharHeight()
         
 
         height = dc.GetCharHeight()
         
@@ -1568,11 +1602,8 @@ class FNBRenderer:
             # On GTK the tabs are should be larger
             tabHeight += 6
 
             # On GTK the tabs are should be larger
             tabHeight += 6
 
-        if pc.HasFlag(FNB_VC71):
-            tabHeight = (pc.HasFlag(FNB_BOTTOM) and [tabHeight - 4] or [tabHeight])[0]
-        elif pc.HasFlag(FNB_FANCY_TABS):
-            tabHeight = (pc.HasFlag(FNB_BOTTOM) and [tabHeight - 2] or [tabHeight])[0]
-
+        self._tabHeight = tabHeight
+        
         return tabHeight
 
 
         return tabHeight
 
 
@@ -1679,13 +1710,13 @@ class FNBRenderer:
         
         # Draw labels
         normalFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
         
         # Draw labels
         normalFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
-        boldFont = normalFont
+        boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
         boldFont.SetWeight(wx.FONTWEIGHT_BOLD)
         dc.SetFont(boldFont)
 
         posx = pc._pParent.GetPadding()
 
         boldFont.SetWeight(wx.FONTWEIGHT_BOLD)
         dc.SetFont(boldFont)
 
         posx = pc._pParent.GetPadding()
 
-        # Update all the tabs from 0 to 'pc.self._nFrom' to be non visible
+        # Update all the tabs from 0 to 'pc._nFrom' to be non visible
         for i in xrange(pc._nFrom):
         
             pc._pagesInfoVec[i].SetPosition(wx.Point(-1, -1))
         for i in xrange(pc._nFrom):
         
             pc._pagesInfoVec[i].SetPosition(wx.Point(-1, -1))
@@ -1751,6 +1782,48 @@ class FNBRenderer:
         self.DrawDropDownArrow(pc, dc)
 
 
         self.DrawDropDownArrow(pc, dc)
 
 
+    def DrawDragHint(self, pc, tabIdx):
+        """
+        Draws tab drag hint, the default implementation is to do nothing.
+        You can override this function to provide a nice feedback to user.
+        """
+        
+        pass
+
+
+    def NumberTabsCanFit(self, pageContainer, fr=-1):
+
+        pc = pageContainer
+        
+        rect = pc.GetClientRect()
+        clientWidth = rect.width
+
+        vTabInfo = []
+
+        tabHeight = self.CalcTabHeight(pageContainer)
+
+        # The drawing starts from posx 
+        posx = pc._pParent.GetPadding()
+
+        if fr < 0:
+            fr = pc._nFrom
+
+        for i in xrange(fr, len(pc._pagesInfoVec)):
+
+            tabWidth = self.CalcTabWidth(pageContainer, i, tabHeight) 
+            if posx + tabWidth + self.GetButtonsAreaLength(pc) >= clientWidth:
+                break; 
+
+            # Add a result to the returned vector 
+            tabRect = wx.Rect(posx, VERTICAL_BORDER_PADDING, tabWidth , tabHeight)
+            vTabInfo.append(tabRect)
+
+            # Advance posx 
+            posx += tabWidth + FNB_HEIGHT_SPACER
+
+        return vTabInfo
+
+    
 # ---------------------------------------------------------------------------- #
 # Class FNBRendererMgr
 # A manager that handles all the renderers defined below and calls the
 # ---------------------------------------------------------------------------- #
 # Class FNBRendererMgr
 # A manager that handles all the renderers defined below and calls the
@@ -1947,14 +2020,15 @@ class FNBRendererVC71(FNBRenderer):
         if tabIdx == pc.GetSelection():
         
             posy = (pc.HasFlag(FNB_BOTTOM) and [0] or [VERTICAL_BORDER_PADDING])[0]
         if tabIdx == pc.GetSelection():
         
             posy = (pc.HasFlag(FNB_BOTTOM) and [0] or [VERTICAL_BORDER_PADDING])[0]
-            dc.DrawRectangle(posx, posy, tabWidth, tabHeight - 1)
+            tabH = (pc.HasFlag(FNB_BOTTOM) and [tabHeight - 5] or [tabHeight - 3])[0]
+            dc.DrawRectangle(posx, posy, tabWidth, tabH) 
 
             # Draw a black line on the left side of the
             # rectangle
             dc.SetPen(wx.BLACK_PEN)
 
             blackLineY1 = VERTICAL_BORDER_PADDING
 
             # Draw a black line on the left side of the
             # rectangle
             dc.SetPen(wx.BLACK_PEN)
 
             blackLineY1 = VERTICAL_BORDER_PADDING
-            blackLineY2 = (pc.HasFlag(FNB_BOTTOM) and [pc.GetSize().y - 5] or [pc.GetSize().y - 3])[0]
+            blackLineY2 = tabH
             dc.DrawLine(posx + tabWidth, blackLineY1, posx + tabWidth, blackLineY2)
 
             # To give the tab more 3D look we do the following
             dc.DrawLine(posx + tabWidth, blackLineY1, posx + tabWidth, blackLineY2)
 
             # To give the tab more 3D look we do the following
@@ -1993,7 +2067,7 @@ class FNBRendererVC71(FNBRenderer):
         # The width of the images are 16 pixels
         padding = pc.GetParent().GetPadding()
         hasImage = pc._pagesInfoVec[tabIdx].GetImageIndex() != -1
         # The width of the images are 16 pixels
         padding = pc.GetParent().GetPadding()
         hasImage = pc._pagesInfoVec[tabIdx].GetImageIndex() != -1
-        imageYCoord = (pc.HasFlag(FNB_BOTTOM) and [6] or [8])[0]
+        imageYCoord = (pc.HasFlag(FNB_BOTTOM) and [5] or [8])[0]
 
         if hasImage:
             textOffset = 2*pc._pParent._nPadding + 16
 
         if hasImage:
             textOffset = 2*pc._pParent._nPadding + 16
@@ -2058,7 +2132,7 @@ class FNBRendererFancy(FNBRenderer):
         if tabIdx == pc.GetSelection():
         
             posy = (pc.HasFlag(FNB_BOTTOM) and [2] or [VERTICAL_BORDER_PADDING])[0]
         if tabIdx == pc.GetSelection():
         
             posy = (pc.HasFlag(FNB_BOTTOM) and [2] or [VERTICAL_BORDER_PADDING])[0]
-            th = (pc.HasFlag(FNB_BOTTOM) and [tabHeight - 2] or [tabHeight - 5])[0]
+            th = tabHeight - 5
 
             rect = wx.Rect(posx, posy, tabWidth, th)
 
 
             rect = wx.Rect(posx, posy, tabWidth, th)
 
@@ -2166,7 +2240,7 @@ class FNBRendererVC8(FNBRenderer):
 
         # Set the font for measuring the tab height
         normalFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
 
         # Set the font for measuring the tab height
         normalFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
-        boldFont = normalFont
+        boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
         boldFont.SetWeight(wx.FONTWEIGHT_BOLD)
 
         # Calculate the number of rows required for drawing the tabs
         boldFont.SetWeight(wx.FONTWEIGHT_BOLD)
 
         # Calculate the number of rows required for drawing the tabs
@@ -2467,8 +2541,8 @@ class FNBRendererVC8(FNBRenderer):
             pc._colorTo   = LightColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE), 0) 
             pc._colorFrom = LightColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE), 60)
         
             pc._colorTo   = LightColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE), 0) 
             pc._colorFrom = LightColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE), 60)
         
-        col2 = (pc.HasFlag(FNB_BOTTOM) and [pc._pParent.GetGradientColourTo()] or [pc._pParent.GetGradientColourFrom()])[0]
-        col1 = (pc.HasFlag(FNB_BOTTOM) and [pc._pParent.GetGradientColourFrom()] or [pc._pParent.GetGradientColourTo()])[0]
+        col2 = pc._pParent.GetGradientColourTo()
+        col1 = pc._pParent.GetGradientColourFrom()
 
         # If colorful tabs style is set, override the tab color
         if pc.HasFlag(FNB_COLORFUL_TABS):
 
         # If colorful tabs style is set, override the tab color
         if pc.HasFlag(FNB_COLORFUL_TABS):
@@ -2752,11 +2826,17 @@ class FlatNotebook(wx.Panel):
 
         # Set default page height
         dc = wx.ClientDC(self)
 
         # Set default page height
         dc = wx.ClientDC(self)
-        font = self.GetFont()
-        font.SetWeight(wx.FONTWEIGHT_BOLD)
-        dc.SetFont(font)
-        height = dc.GetCharHeight()
         
         
+        if "__WXGTK__" in wx.PlatformInfo:
+            # For GTK it seems that we must do this steps in order
+            # for the tabs will get the proper height on initialization
+            # on MSW, preforming these steps yields wierd results
+            boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
+            boldFont.SetWeight(wx.FONTWEIGHT_BOLD)
+            dc.SetFont(boldFont)
+        
+        height = dc.GetCharHeight()
+
         tabHeight = height + FNB_HEIGHT_SPACER         # We use 8 pixels as padding
         
         if "__WXGTK__" in wx.PlatformInfo:
         tabHeight = height + FNB_HEIGHT_SPACER         # We use 8 pixels as padding
         
         if "__WXGTK__" in wx.PlatformInfo:
@@ -2826,7 +2906,7 @@ class FlatNotebook(wx.Panel):
             event.SetOldSelection(oldSelection)
             event.SetEventObject(self)
             
             event.SetOldSelection(oldSelection)
             event.SetEventObject(self)
             
-            if not self.GetEventHandler().ProcessEvent(event) or event.IsAllowed():
+            if not self.GetEventHandler().ProcessEvent(event) or event.IsAllowed() or len(self._windows) == 0:
                 bSelected = True            
         
         curSel = self._pages.GetSelection()
                 bSelected = True            
         
         curSel = self._pages.GetSelection()
@@ -2866,21 +2946,21 @@ class FlatNotebook(wx.Panel):
 
             # Hide the page
             page.Hide()
 
             # Hide the page
             page.Hide()
-        
+
+        self.Thaw()        
         self._mainSizer.Layout()
         self._mainSizer.Layout()
-        self.Thaw()
         self.Refresh()
 
         return True        
 
 
         self.Refresh()
 
         return True        
 
 
-    def SetImageList(self, imglist):
+    def SetImageList(self, imageList):
         """
         Sets the image list for the page control. It does not take ownership
         of the image list, you must delete it yourself.
         """
 
         """
         Sets the image list for the page control. It does not take ownership
         of the image list, you must delete it yourself.
         """
 
-        self._pages.SetImageList(imglist)
+        self._pages.SetImageList(imageList)
 
 
     def GetImageList(self):
 
 
     def GetImageList(self):
@@ -2941,7 +3021,7 @@ class FlatNotebook(wx.Panel):
             event.SetOldSelection(oldSelection)
             event.SetEventObject(self)
             
             event.SetOldSelection(oldSelection)
             event.SetEventObject(self)
             
-            if not self.GetEventHandler().ProcessEvent(event) or event.IsAllowed():
+            if not self.GetEventHandler().ProcessEvent(event) or event.IsAllowed() or len(self._windows) == 0:
                 bSelected = True            
         
         self._pages.InsertPage(indx, text, bSelected, imageId)
                 bSelected = True            
         
         self._pages.InsertPage(indx, text, bSelected, imageId)
@@ -2971,9 +3051,9 @@ class FlatNotebook(wx.Panel):
         
             # Hide the page
             page.Hide()
         
             # Hide the page
             page.Hide()
-        
+
         self.Thaw()
         self.Thaw()
-        self._mainSizer.Layout()
+        self._mainSizer.Layout()        
         self.Refresh()
 
         return True
         self.Refresh()
 
         return True
@@ -3124,17 +3204,18 @@ class FlatNotebook(wx.Panel):
         return self._pages.GetSelection()
 
 
         return self._pages.GetSelection()
 
 
-    def AdvanceSelection(self, bForward=True):
+    def AdvanceSelection(self, forward=True):
         """
         Cycles through the tabs.
         The call to this function generates the page changing events.
         """
 
         """
         Cycles through the tabs.
         The call to this function generates the page changing events.
         """
 
-        self._pages.AdvanceSelection(bForward)
+        self._pages.AdvanceSelection(forward)
 
 
     def GetPageCount(self):
         """ Returns the number of pages in the L{FlatNotebook} control. """
 
 
     def GetPageCount(self):
         """ Returns the number of pages in the L{FlatNotebook} control. """
+
         return self._pages.GetPageCount()
 
 
         return self._pages.GetPageCount()
 
 
@@ -3142,6 +3223,8 @@ class FlatNotebook(wx.Panel):
         """ Handles the wx.EVT_NAVIGATION_KEY event for L{FlatNotebook}. """
 
         if event.IsWindowChange():
         """ Handles the wx.EVT_NAVIGATION_KEY event for L{FlatNotebook}. """
 
         if event.IsWindowChange():
+            if len(self._windows) == 0:
+                return
             # change pages
             if self.HasFlag(FNB_SMART_TABS):
                 if not self._popupWin:
             # change pages
             if self.HasFlag(FNB_SMART_TABS):
                 if not self._popupWin:
@@ -3238,6 +3321,8 @@ class FlatNotebook(wx.Panel):
         """ Sets the L{FlatNotebook} window style flags. """
             
         wx.Panel.SetWindowStyleFlag(self, style)
         """ Sets the L{FlatNotebook} window style flags. """
             
         wx.Panel.SetWindowStyleFlag(self, style)
+        renderer = self._pages._mgr.GetRenderer(self.GetWindowStyleFlag())
+        renderer._tabHeight = None
 
         if self._pages:
         
 
         if self._pages:
         
@@ -3245,6 +3330,10 @@ class FlatNotebook(wx.Panel):
             # refreshing the tab container is not enough
             self.SetSelection(self._pages._iActivePage)
 
             # refreshing the tab container is not enough
             self.SetSelection(self._pages._iActivePage)
 
+        if not self._pages.HasFlag(FNB_HIDE_ON_SINGLE_TAB):
+            #For Redrawing the Tabs once you remove the Hide tyle
+            self._pages._ReShow()
+
 
     def RemovePage(self, page):
         """ Deletes the specified page, without deleting the associated window. """
 
     def RemovePage(self, page):
         """ Deletes the specified page, without deleting the associated window. """
@@ -3287,10 +3376,10 @@ class FlatNotebook(wx.Panel):
         self._pages._pRightClickMenu = menu
 
 
         self._pages._pRightClickMenu = menu
 
 
-    def GetPageText(self, page):
+    def GetPageText(self, nPage):
         """ Returns the tab caption. """
 
         """ Returns the tab caption. """
 
-        return self._pages.GetPageText(page)
+        return self._pages.GetPageText(nPage)
 
 
     def SetGradientColours(self, fr, to, border):
 
 
     def SetGradientColours(self, fr, to, border):
@@ -3349,22 +3438,22 @@ class FlatNotebook(wx.Panel):
         return self._pages._activeTextColor
 
 
         return self._pages._activeTextColor
 
 
-    def SetPageImage(self, page, imgindex):
+    def SetPageImage(self, page, image):
         """
         Sets the image index for the given page. Image is an index into the
         image list which was set with SetImageList.
         """
 
         """
         Sets the image index for the given page. Image is an index into the
         image list which was set with SetImageList.
         """
 
-        self._pages.SetPageImage(page, imgindex)
+        self._pages.SetPageImage(page, image)
 
 
 
 
-    def GetPageImage(self, page):
+    def GetPageImage(self, nPage):
         """
         Returns the image index for the given page. Image is an index into the
         image list which was set with SetImageList.
         """
 
         """
         Returns the image index for the given page. Image is an index into the
         image list which was set with SetImageList.
         """
 
-        return self._pages.GetPageImage(page)
+        return self._pages.GetPageImage(nPage)
 
 
     def GetEnabled(self, page):
 
 
     def GetEnabled(self, page):
@@ -3462,10 +3551,11 @@ class PageContainer(wx.Panel):
         # Set default page height, this is done according to the system font
         memDc = wx.MemoryDC()
         memDc.SelectObject(wx.EmptyBitmap(1,1))
         # Set default page height, this is done according to the system font
         memDc = wx.MemoryDC()
         memDc.SelectObject(wx.EmptyBitmap(1,1))
-        normalFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
-        boldFont = normalFont
-        boldFont.SetWeight(wx.BOLD)
-        memDc.SetFont(boldFont)
+    
+        if "__WXGTK__" in wx.PlatformInfo:
+            boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
+            boldFont.SetWeight(wx.BOLD)
+            memDc.SetFont(boldFont)
 
         height = memDc.GetCharHeight()
         tabHeight = height + FNB_HEIGHT_SPACER # We use 10 pixels as padding
 
         height = memDc.GetCharHeight()
         tabHeight = height + FNB_HEIGHT_SPACER # We use 10 pixels as padding
@@ -3496,23 +3586,25 @@ class PageContainer(wx.Panel):
         pass
 
     
         pass
 
     
+    def _ReShow(self):
+        """ Handles the Redraw of the tabs when the FNB_HIDE_ON_SINGLE_TAB has been removed """
+        self.Show()
+        self.GetParent()._mainSizer.Layout()
+        self.Refresh()
+
+
     def OnPaint(self, event):
         """ Handles the wx.EVT_PAINT event for L{PageContainer}."""
 
     def OnPaint(self, event):
         """ Handles the wx.EVT_PAINT event for L{PageContainer}."""
 
-        # Currently having problems with buffered DCs because of
-        # recent changes.  Just do the buffering ourselves instead.
-        #dc = wx.BufferedPaintDC(self)
-        size = self.GetSize()
-        bmp = wx.EmptyBitmap(*size)
-        dc = wx.MemoryDC()
-        dc.SelectObject(bmp)
-        
+        dc = wx.BufferedPaintDC(self)
         renderer = self._mgr.GetRenderer(self.GetParent().GetWindowStyleFlag())
         renderer.DrawTabs(self, dc)
 
         renderer = self._mgr.GetRenderer(self.GetParent().GetWindowStyleFlag())
         renderer.DrawTabs(self, dc)
 
-        pdc = wx.PaintDC(self)
-        pdc.Blit(0,0, size.width, size.height, dc, 0,0)
-        
+        if self.HasFlag(FNB_HIDE_ON_SINGLE_TAB) and len(self._pagesInfoVec) <= 1:
+            self.Hide()
+            self.GetParent()._mainSizer.Layout()
+            self.Refresh()
+
 
     def AddPage(self, caption, selected=True, imgindex=-1):
         """
 
     def AddPage(self, caption, selected=True, imgindex=-1):
         """
@@ -3566,6 +3658,21 @@ class PageContainer(wx.Panel):
     def OnSize(self, event):
         """ Handles the wx.EVT_SIZE events for L{PageContainer}. """
 
     def OnSize(self, event):
         """ Handles the wx.EVT_SIZE events for L{PageContainer}. """
 
+        # When resizing the control, try to fit to screen as many tabs as we can 
+        style = self.GetParent().GetWindowStyleFlag() 
+        renderer = self._mgr.GetRenderer(style)
+        
+        fr = 0
+        page = self.GetSelection()
+        
+        for fr in xrange(self._nFrom):
+            vTabInfo = renderer.NumberTabsCanFit(self, fr)
+            if page - fr >= len(vTabInfo):
+                continue
+            break
+
+        self._nFrom = fr
+
         self.Refresh() # Call on paint
         event.Skip()
 
         self.Refresh() # Call on paint
         event.Skip()
 
@@ -3589,30 +3696,26 @@ class PageContainer(wx.Panel):
 
     def OnRightDown(self, event):
         """ Handles the wx.EVT_RIGHT_DOWN events for L{PageContainer}. """
 
     def OnRightDown(self, event):
         """ Handles the wx.EVT_RIGHT_DOWN events for L{PageContainer}. """
-
-        if self._pRightClickMenu:
         
         
-            where, tabIdx = self.HitTest(event.GetPosition())
+        where, tabIdx = self.HitTest(event.GetPosition())
 
 
-            if where in [FNB_TAB, FNB_TAB_X]:
+        if where in [FNB_TAB, FNB_TAB_X]:
 
 
-                if self._pagesInfoVec[tabIdx].GetEnabled():
-                    # Set the current tab to be active
-                    self.SetSelection(tabIdx)
-
-                    # If the owner has defined a context menu for the tabs,
-                    # popup the right click menu
-                    if self._pRightClickMenu:
-                        self.PopupMenu(self._pRightClickMenu)
-                    else:
-                        # send a message to popup a custom menu
-                        event = FlatNotebookEvent(wxEVT_FLATNOTEBOOK_PAGE_CONTEXT_MENU, self.GetParent().GetId())
-                        event.SetSelection(tabIdx)
-                        event.SetOldSelection(self._iActivePage)
-                        event.SetEventObject(self.GetParent())
-                        self.GetParent().GetEventHandler().ProcessEvent(event)
-                
-            event.Skip()
+            if self._pagesInfoVec[tabIdx].GetEnabled():
+                # Fire events and eventually (if allowed) change selection
+                self.FireEvent(tabIdx)
+
+                # send a message to popup a custom menu
+                event = FlatNotebookEvent(wxEVT_FLATNOTEBOOK_PAGE_CONTEXT_MENU, self.GetParent().GetId())
+                event.SetSelection(tabIdx)
+                event.SetOldSelection(self._iActivePage)
+                event.SetEventObject(self.GetParent())
+                self.GetParent().GetEventHandler().ProcessEvent(event)
+
+                if self._pRightClickMenu:
+                    self.PopupMenu(self._pRightClickMenu)
+            
+        event.Skip()
 
 
     def OnLeftDown(self, event):
 
 
     def OnLeftDown(self, event):
@@ -3646,25 +3749,10 @@ class PageContainer(wx.Panel):
         elif self._nLeftClickZone == FNB_TAB:
             
             if self._iActivePage != tabIdx:
         elif self._nLeftClickZone == FNB_TAB:
             
             if self._iActivePage != tabIdx:
-            
+                
                 # In case the tab is disabled, we dont allow to choose it
                 if self._pagesInfoVec[tabIdx].GetEnabled():
                 # In case the tab is disabled, we dont allow to choose it
                 if self._pagesInfoVec[tabIdx].GetEnabled():
-
-                    oldSelection = self._iActivePage
-
-                    event = FlatNotebookEvent(wxEVT_FLATNOTEBOOK_PAGE_CHANGING, self.GetParent().GetId())
-                    event.SetSelection(tabIdx)
-                    event.SetOldSelection(oldSelection)
-                    event.SetEventObject(self.GetParent())
-                    
-                    if not self.GetParent().GetEventHandler().ProcessEvent(event) or event.IsAllowed():
-                    
-                        self.SetSelection(tabIdx)
-
-                        # Fire a wxEVT_FLATNOTEBOOK_PAGE_CHANGED event
-                        event.SetEventType(wxEVT_FLATNOTEBOOK_PAGE_CHANGED)
-                        event.SetOldSelection(oldSelection)
-                        self.GetParent().GetEventHandler().ProcessEvent(event)        
+                    self.FireEvent(tabIdx)
 
 
     def OnLeftUp(self, event):
 
 
     def OnLeftUp(self, event):
@@ -3867,22 +3955,18 @@ class PageContainer(wx.Panel):
                 da_page.SetFocus()
         
         if not self.IsTabVisible(page):
                 da_page.SetFocus()
         
         if not self.IsTabVisible(page):
-        
-            if page == len(self._pagesInfoVec) - 1:
-                # Incase the added tab is last,
-                # the function IsTabVisible() will always return False
-                # and thus will cause an evil behaviour that the new
-                # tab will hide all other tabs, we need to check if the
-                # new selected tab can fit to the current screen
-                if not self.CanFitToScreen(page):
-                    self._nFrom = page
-                            
-            else:
+            # Try to remove one tab from start and try again
+            
+            if not self.CanFitToScreen(page):
 
 
-                if not self.CanFitToScreen(page):
-                    # Redraw the tabs starting from page
+                if self._nFrom > page:
                     self._nFrom = page
                     self._nFrom = page
-                    
+                else:
+                    while self._nFrom < page:
+                        self._nFrom += 1
+                        if self.CanFitToScreen(page):
+                            break
         self.Refresh()
 
 
         self.Refresh()
 
 
@@ -4033,14 +4117,14 @@ class PageContainer(wx.Panel):
                     wx.SetCursor(wx.StockCursor(wx.CURSOR_NO_ENTRY))
                 
                 # Support for drag and drop
                     wx.SetCursor(wx.StockCursor(wx.CURSOR_NO_ENTRY))
                 
                 # Support for drag and drop
-                if event.LeftIsDown() and not (style & FNB_NODRAG):
+                if event.Dragging() and not (style & FNB_NODRAG):
 
                     self._isdragging = True                
                     draginfo = FNBDragInfo(self, tabIdx)
                     drginfo = cPickle.dumps(draginfo)
                     dataobject = wx.CustomDataObject(wx.CustomDataFormat("FlatNotebook"))
                     dataobject.SetData(drginfo)
 
                     self._isdragging = True                
                     draginfo = FNBDragInfo(self, tabIdx)
                     drginfo = cPickle.dumps(draginfo)
                     dataobject = wx.CustomDataObject(wx.CustomDataFormat("FlatNotebook"))
                     dataobject.SetData(drginfo)
-                    dragSource = wx.DropSource(self)
+                    dragSource = FNBDropSource(self)
                     dragSource.SetData(dataobject)
                     dragSource.DoDragDrop(wx.Drag_DefaultMove)
                     
                     dragSource.SetData(dataobject)
                     dragSource.DoDragDrop(wx.Drag_DefaultMove)
                     
@@ -4082,6 +4166,9 @@ class PageContainer(wx.Panel):
     def GetLastVisibleTab(self):
         """ Returns the last visible tab. """
 
     def GetLastVisibleTab(self):
         """ Returns the last visible tab. """
 
+        if self._nFrom < 0:
+            return -1
+
         ii = 0
         
         for ii in xrange(self._nFrom, len(self._pagesInfoVec)):
         ii = 0
         
         for ii in xrange(self._nFrom, len(self._pagesInfoVec)):
@@ -4178,7 +4265,6 @@ class PageContainer(wx.Panel):
 
         nMax = self.GetPageCount() - 1
         
 
         nMax = self.GetPageCount() - 1
         
-        oldSelection = self._iActivePage
         if bForward:
             newSelection = (nSel == nMax and [0] or [nSel + 1])[0]
         else:
         if bForward:
             newSelection = (nSel == nMax and [0] or [nSel + 1])[0]
         else:
@@ -4186,20 +4272,8 @@ class PageContainer(wx.Panel):
 
         if not self._pagesInfoVec[newSelection].GetEnabled():
             return
 
         if not self._pagesInfoVec[newSelection].GetEnabled():
             return
-        
-        event = FlatNotebookEvent(wxEVT_FLATNOTEBOOK_PAGE_CHANGING, self.GetParent().GetId())
-        event.SetSelection(newSelection)
-        event.SetOldSelection(oldSelection)
-        event.SetEventObject(self.GetParent())
-        
-        if not self.GetParent().GetEventHandler().ProcessEvent(event) or event.IsAllowed():
-        
-            self.SetSelection(newSelection)
 
 
-            # Fire a wxEVT_FLATNOTEBOOK_PAGE_CHANGED event
-            event.SetEventType(wxEVT_FLATNOTEBOOK_PAGE_CHANGED)
-            event.SetOldSelection(oldSelection)
-            self.GetParent().GetEventHandler().ProcessEvent(event)       
+        self.FireEvent(newSelection)
 
 
     def OnMouseLeave(self, event):
 
 
     def OnMouseLeave(self, event):
@@ -4304,7 +4378,7 @@ class PageContainer(wx.Panel):
             
                 if where == FNB_TAB:
                     self.MoveTabPage(nTabPage, nIndex)
             
                 if where == FNB_TAB:
                     self.MoveTabPage(nTabPage, nIndex)
-        
+                           
         elif self.GetParent().GetWindowStyleFlag() & FNB_ALLOW_FOREIGN_DND:
         
             if wx.Platform in ["__WXMSW__", "__WXGTK__"]:
         elif self.GetParent().GetWindowStyleFlag() & FNB_ALLOW_FOREIGN_DND:
         
             if wx.Platform in ["__WXMSW__", "__WXGTK__"]:
@@ -4321,7 +4395,7 @@ class PageContainer(wx.Panel):
 
                         if imageindex >= 0:
 
 
                         if imageindex >= 0:
 
-                            bmp = oldNotebook.GetImageList().GetBitmap(imageindex)
+                            bmp = oldNotebook.GetImageList().GetIcon(imageindex)
                             newImageList = newNotebook.GetImageList()
     
                             if not newImageList:
                             newImageList = newNotebook.GetImageList()
     
                             if not newImageList:
@@ -4331,7 +4405,7 @@ class PageContainer(wx.Panel):
                             else:
                                 imageindex = newImageList.GetImageCount()
 
                             else:
                                 imageindex = newImageList.GetImageCount()
 
-                            newImageList.Add(bmp)
+                            newImageList.AddIcon(bmp)
                             newNotebook.SetImageList(newImageList)
                                 
                         newNotebook.InsertPage(nIndex, window, caption, True, imageindex)
                             newNotebook.SetImageList(newImageList)
                                 
                         newNotebook.InsertPage(nIndex, window, caption, True, imageindex)
@@ -4401,39 +4475,12 @@ class PageContainer(wx.Panel):
         style = self.GetParent().GetWindowStyleFlag()
         render = self._mgr.GetRenderer(style)
 
         style = self.GetParent().GetWindowStyleFlag()
         render = self._mgr.GetRenderer(style)
 
-        if not self.HasFlag(FNB_VC8):
-            rect = self.GetClientRect();
-            clientWidth = rect.width;
-            tabHeight = render.CalcTabHeight(self)
-            tabWidth = render.CalcTabWidth(self, page, tabHeight)
-
-            posx = self._pParent._nPadding
-
-            if self._nFrom >= 0:
-
-                for i in xrange(self._nFrom, len(self._pagesInfoVec)):
-
-                    if self._pagesInfoVec[i].GetPosition() == wx.Point(-1, -1):
-                        break
-                    
-                    posx += self._pagesInfoVec[i].GetSize().x
-
-            if posx + tabWidth + render.GetButtonsAreaLength(self) >= clientWidth:
-                return False
-
-            return True
-
-        else:
+        vTabInfo = render.NumberTabsCanFit(self)
 
 
-            # TODO:: this is ugly and should be improved, we should *never* access the
-            # raw pointer directly like we do here (render.Get())
-            vc8_render = render
-            vTabInfo = vc8_render.NumberTabsCanFit(self)
-
-            if page - self._nFrom >= len(vTabInfo):
-                return False
-            
-            return True
+        if page - self._nFrom >= len(vTabInfo):
+            return False
+        
+        return True
 
 
     def GetNumOfVisibleTabs(self):
 
 
     def GetNumOfVisibleTabs(self):
@@ -4530,6 +4577,7 @@ class PageContainer(wx.Panel):
             #   item.SetBitmaps( (*m_ImageList)[pi.GetImageIndex()] );
 
             popupMenu.AppendItem(item)
             #   item.SetBitmaps( (*m_ImageList)[pi.GetImageIndex()] );
 
             popupMenu.AppendItem(item)
+            item.Enable(pi.GetEnabled())
             
         self.PopupMenu(popupMenu)
 
             
         self.PopupMenu(popupMenu)
 
@@ -4538,8 +4586,36 @@ class PageContainer(wx.Panel):
         """ Handles the wx.EVT_MENU event for L{PageContainer}. """
 
         selection = event.GetId()
         """ Handles the wx.EVT_MENU event for L{PageContainer}. """
 
         selection = event.GetId()
-        self._pParent.SetSelection(selection)
+        self.FireEvent(selection)
+
+
+    def FireEvent(self, selection):
+        """
+        Fires the wxEVT_FLATNOTEBOOK_PAGE_CHANGING and wxEVT_FLATNOTEBOOK_PAGE_CHANGED events
+        called from other methods (from menu selection or Smart Tabbing).
+        Utility function.
+        """
+
+        if selection == self._iActivePage:
+            # No events for the same selection
+            return
+        
+        oldSelection = self._iActivePage
+
+        event = FlatNotebookEvent(wxEVT_FLATNOTEBOOK_PAGE_CHANGING, self.GetParent().GetId())
+        event.SetSelection(selection)
+        event.SetOldSelection(oldSelection)
+        event.SetEventObject(self.GetParent())
+        
+        if not self.GetParent().GetEventHandler().ProcessEvent(event) or event.IsAllowed():
+        
+            self.SetSelection(selection)
 
 
+            # Fire a wxEVT_FLATNOTEBOOK_PAGE_CHANGED event
+            event.SetEventType(wxEVT_FLATNOTEBOOK_PAGE_CHANGED)
+            event.SetOldSelection(oldSelection)
+            self.GetParent().GetEventHandler().ProcessEvent(event)
+            
 
     def SetImageList(self, imglist):
         """ Sets the image list for the page control. """
 
     def SetImageList(self, imglist):
         """ Sets the image list for the page control. """
@@ -4578,3 +4654,12 @@ class PageContainer(wx.Panel):
         return True 
 
 
         return True 
 
 
+    def DrawDragHint(self):
+        """ Draws small arrow at the place that the tab will be placed. """
+
+        # get the index of tab that will be replaced with the dragged tab
+        pt = wx.GetMousePosition()
+        client_pt = self.ScreenToClient(pt)
+        where, tabIdx = self.HitTest(client_pt)
+        self._mgr.GetRenderer(self.GetParent().GetWindowStyleFlag()).DrawDragHint(self, tabIdx)
+