]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/tabg.cpp
fixed a (harmless) BoundsChecker warning
[wxWidgets.git] / src / generic / tabg.cpp
index 20e96214c016ba826f6ccb4aac7d9dcf2b310c93..33119247e69175e836a5a073c0c05bcaf54d59ba 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     01/02/97
 // RCS-ID:      $Id$
 // Copyright:   (c)
-// Licence:    wxWindows licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
@@ -20,6 +20,8 @@
 #pragma hdrstop
 #endif
 
+#if wxUSE_TAB_DIALOG
+
 #ifndef WX_PRECOMP
 #include "wx/wx.h"
 #endif
 
 #include "wx/tab.h"
 
+// not defined: use old, square tab implementation (fills in tabs)
+// defined: use new, rounded tab implementation (doesn't colour in tabs)
+// #define wxUSE_NEW_METHOD
+
 IMPLEMENT_DYNAMIC_CLASS(wxTabControl, wxObject)
 
 IMPLEMENT_DYNAMIC_CLASS(wxTabLayer, wxList)
@@ -39,7 +45,6 @@ wxTabControl::wxTabControl(wxTabView *v)
 {
   m_view = v;
   m_isSelected = FALSE;
-  m_labelFont = NULL;
   m_offsetX = 0;
   m_offsetY = 0;
   m_width = 0;
@@ -52,41 +57,45 @@ wxTabControl::wxTabControl(wxTabView *v)
 wxTabControl::~wxTabControl(void)
 {
 }
-    
+
 void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
 {
     // Old, but in some ways better (drawing opaque tabs)
-#if 0
+#ifndef wxUSE_NEW_METHOD
   if (!m_view)
     return;
-    
+
   // Top-left of tab view area
   int viewX = m_view->GetViewRect().x;
   int viewY = m_view->GetViewRect().y;
-  
+
   // Top-left of tab control
   int tabX = GetX() + viewX;
   int tabY = GetY() + viewY;
   int tabHeightInc = 0;
   if (m_isSelected)
   {
-    tabHeightInc = (view->GetTabSelectionHeight() - view->GetTabHeight());
+    tabHeightInc = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());
     tabY -= tabHeightInc;
   }
-  
-  dc.SetPen(wxTRANSPARENT_PEN);
+
+  dc.SetPen(*wxTRANSPARENT_PEN);
 
   // Draw grey background
-  if (view->GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
+  if (m_view->GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
   {
-    dc.SetBrush(m_view->GetBackgroundBrush());
+    dc.SetBrush(*m_view->GetBackgroundBrush());
 
     // Add 1 because the pen is transparent. Under Motif, may be different.
+#ifdef __WXMOTIF__
+    dc.DrawRectangle(tabX, tabY, (GetWidth()+1), (GetHeight() + tabHeightInc));
+#else
     dc.DrawRectangle(tabX, tabY, (GetWidth()+1), (GetHeight() + 1 + tabHeightInc));
+#endif
   }
-  
+
   // Draw highlight and shadow
-  dc.SetPen(m_view->GetHighlightPen());
+  dc.SetPen(*m_view->GetHighlightPen());
 
   // Calculate the top of the tab beneath. It's the height of the tab, MINUS
   // a bit if the tab below happens to be selected. Check.
@@ -107,7 +116,7 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
     dc.DrawLine(tabX, tabY, tabX, (tabY + GetHeight() + tabHeightInc - subtractThis));
 
   dc.DrawLine(tabX, tabY, (tabX + GetWidth()), tabY);
-  dc.SetPen(m_view->GetShadowPen());
+  dc.SetPen(*m_view->GetShadowPen());
 
   // Test if we're outside the right-hand edge of the view area
   if (((tabX + GetWidth()) >= m_view->GetViewRect().x + m_view->GetViewRect().width) && (m_view->GetTabStyle() & wxTAB_STYLE_DRAW_BOX))
@@ -126,7 +135,7 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
       (tabX + GetWidth()), (bottomY-1));
 
     // Draw black line to emphasize shadow
-    dc.SetPen(wxBLACK_PEN);
+    dc.SetPen(*wxBLACK_PEN);
     dc.DrawLine((tabX + GetWidth() + 1), (tabY+1),
       (tabX + GetWidth() + 1), bottomY);
 
@@ -139,19 +148,23 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
     if (lastInRow)
     {
       // 25/5/97 UNLESS it's less than the max number of positions in this row
-      
+
       int topY = m_view->GetViewRect().y - m_view->GetTopMargin();
 
       int maxPositions = ((wxTabLayer *)m_view->GetLayers().Nth(0)->Data())->Number();
 
       // Only down to the bottom of the tab, not to the top of the view
-      if ( GetColPosition() < maxPositions )
+      if ( GetRowPosition() < (maxPositions - 1) )
         topY = tabY + GetHeight() + tabHeightInc;
 
+#ifdef __WXMOTIF__
+      topY -= 1;
+#endif
+
       // Shadow
       dc.DrawLine((tabX + GetWidth()), tabY, (tabX + GetWidth()), topY);
       // Draw black line to emphasize shadow
-      dc.SetPen(wxBLACK_PEN);
+      dc.SetPen(*wxBLACK_PEN);
       dc.DrawLine((tabX + GetWidth() + 1), (tabY+1), (tabX + GetWidth() + 1),
          topY);
     }
@@ -166,38 +179,46 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
       if (tabBeneath && tabBeneath->IsSelected())
         subtractThis = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());
 
+#ifdef __WXMOTIF__
+      subtractThis += 1;
+#endif
+
       // Draw only to next tab down.
       dc.DrawLine((tabX + GetWidth()), tabY,
          (tabX + GetWidth()), (tabY + GetHeight() + tabHeightInc - subtractThis));
 
       // Draw black line to emphasize shadow
-      dc.SetPen(wxBLACK_PEN);
+      dc.SetPen(*wxBLACK_PEN);
       dc.DrawLine((tabX + GetWidth() + 1), (tabY+1), (tabX + GetWidth() + 1),
          (tabY + GetHeight() + tabHeightInc - subtractThis));
     }
   }
-  
+
   // Draw centered text
   int textY = tabY + m_view->GetVerticalTabTextSpacing() + tabHeightInc;
 
   if (m_isSelected)
-    dc.SetFont(m_view->GetSelectedTabFont());
+    dc.SetFont(m_view->GetSelectedTabFont());
   else
-    dc.SetFont(GetFont());
+    dc.SetFont(GetFont());
 
   wxColour col(m_view->GetTextColour());
-  dc.SetTextForeground(&col);
-//  dc.SetTextForeground(&(m_view->GetTextColour()));
+  dc.SetTextForeground(col);
   dc.SetBackgroundMode(wxTRANSPARENT);
-  float textWidth, textHeight;
+  long textWidth, textHeight;
   dc.GetTextExtent(GetLabel(), &textWidth, &textHeight);
 
   int textX = (int)(tabX + (GetWidth() - textWidth)/2.0);
+  if (textX < (tabX + 2))
+    textX = (tabX + 2);
+
+  dc.SetClippingRegion(tabX, tabY, GetWidth(), GetHeight());
   dc.DrawText(GetLabel(), textX, textY);
+  dc.DestroyClippingRegion();
 
   if (m_isSelected)
   {
-    dc.SetPen(m_view->GetHighlightPen());
+    dc.SetPen(*m_view->GetHighlightPen());
 
     // Draw white highlight from the tab's left side to the left hand edge of the view
     dc.DrawLine(m_view->GetViewRect().x, (tabY + GetHeight() + tabHeightInc),
@@ -207,262 +228,261 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
     dc.DrawLine((tabX + GetWidth()), (tabY + GetHeight() + tabHeightInc),
      m_view->GetViewRect().x + m_view->GetViewRect().width, (tabY + GetHeight() + tabHeightInc));
   }
-#endif
+#else
+    // New HEL version with rounder tabs
+
+    if (!m_view) return;
+
+    int tabInc   = 0;
+    if (m_isSelected)
+    {
+        tabInc = m_view->GetTabSelectionHeight() - m_view->GetTabHeight();
+    }
+    int tabLeft  = GetX() + m_view->GetViewRect().x;
+    int tabTop   = GetY() + m_view->GetViewRect().y - tabInc;
+    int tabRight = tabLeft + m_view->GetTabWidth();
+    int left     = m_view->GetViewRect().x;
+    int top      = tabTop + m_view->GetTabHeight() + tabInc;
+    int right    = left + m_view->GetViewRect().width;
+    int bottom   = top + m_view->GetViewRect().height;
+
+    if (m_isSelected)
+    {
+        // TAB is selected - draw TAB and the View's full outline
+
+        dc.SetPen(*(m_view->GetHighlightPen()));
+        wxPoint pnts[10];
+        int n = 0;
+        pnts[n].x = left;            pnts[n++].y = bottom;
+        pnts[n].x = left;             pnts[n++].y = top;
+        pnts[n].x = tabLeft;         pnts[n++].y = top;
+        pnts[n].x = tabLeft;            pnts[n++].y = tabTop + 2;
+        pnts[n].x = tabLeft + 2;        pnts[n++].y = tabTop;
+        pnts[n].x = tabRight - 1;    pnts[n++].y = tabTop;
+        dc.DrawLines(n, pnts);
+        if (!lastInRow)
+        {
+            dc.DrawLine(
+                    (tabRight + 2),
+                    top,
+                    right,
+                    top
+                    );
+        }
+
+        dc.SetPen(*(m_view->GetShadowPen()));
+        dc.DrawLine(
+                tabRight,
+                tabTop + 2,
+                tabRight,
+                top
+                );
+        dc.DrawLine(
+                right,
+                top,
+                right,
+                bottom
+                );
+        dc.DrawLine(
+                right,
+                bottom,
+                left,
+                bottom
+                );
+
+        dc.SetPen(*wxBLACK_PEN);
+        dc.DrawPoint(
+                tabRight,
+                tabTop + 1
+                );
+        dc.DrawPoint(
+                tabRight + 1,
+                tabTop + 2
+                );
+        if (lastInRow)
+        {
+            dc.DrawLine(
+                tabRight + 1,
+                bottom,
+                tabRight + 1,
+                tabTop + 1
+                );
+        }
+        else
+        {
+            dc.DrawLine(
+                tabRight + 1,
+                tabTop + 2,
+                tabRight + 1,
+                top
+                );
+            dc.DrawLine(
+                right + 1,
+                top,
+                right + 1,
+                bottom + 1
+                );
+        }
+        dc.DrawLine(
+                right + 1,
+                bottom + 1,
+                left + 1,
+                bottom + 1
+                );
+    }
+    else
+    {
+        // TAB is not selected - just draw TAB outline and RH edge
+        // if the TAB is the last in the row
+
+        int maxPositions = ((wxTabLayer*)m_view->GetLayers().Nth(0)->Data())->Number();
+        wxTabControl* tabBelow = 0;
+        wxTabControl* tabBelowRight = 0;
+        if (GetColPosition() > 0)
+        {
+            tabBelow = m_view->FindTabControlForPosition(
+                        GetColPosition() - 1,
+                        GetRowPosition()
+                        );
+        }
+        if (!lastInRow && GetColPosition() > 0)
+        {
+            tabBelowRight = m_view->FindTabControlForPosition(
+                        GetColPosition() - 1,
+                        GetRowPosition() + 1
+                        );
+        }
+
+        float raisedTop = top - m_view->GetTabSelectionHeight() +
+                            m_view->GetTabHeight();
+
+        dc.SetPen(*(m_view->GetHighlightPen()));
+        wxPoint pnts[10];
+        int n = 0;
+
+        pnts[n].x = tabLeft;
+
+        if (tabBelow && tabBelow->IsSelected())
+        {
+            pnts[n++].y = (long)raisedTop;
+        }
+        else
+        {
+            pnts[n++].y = top;
+        }
+        pnts[n].x = tabLeft;            pnts[n++].y = tabTop + 2;
+        pnts[n].x = tabLeft + 2;        pnts[n++].y = tabTop;
+        pnts[n].x = tabRight - 1;    pnts[n++].y = tabTop;
+        dc.DrawLines(n, pnts);
+
+        dc.SetPen(*(m_view->GetShadowPen()));
+        if (GetRowPosition() >= maxPositions - 1)
+        {
+            dc.DrawLine(
+                    tabRight,
+                    (tabTop + 2),
+                    tabRight,
+                    bottom
+                    );
+            dc.DrawLine(
+                    tabRight,
+                    bottom,
+                    (tabRight - m_view->GetHorizontalTabOffset()),
+                    bottom
+                    );
+        }
+        else
+        {
+            if (tabBelowRight && tabBelowRight->IsSelected())
+            {
+                dc.DrawLine(
+                        tabRight,
+                        (long)raisedTop,
+                        tabRight,
+                        tabTop + 1
+                        );
+            }
+            else
+            {
+                dc.DrawLine(
+                        tabRight,
+                        top - 1,
+                        tabRight,
+                        tabTop + 1
+                        );
+            }
+        }
+
+        dc.SetPen(*wxBLACK_PEN);
+        dc.DrawPoint(
+                tabRight,
+                tabTop + 1
+                );
+        dc.DrawPoint(
+                tabRight + 1,
+                tabTop + 2
+                );
+        if (GetRowPosition() >= maxPositions - 1)
+        {
+            // draw right hand edge to bottom of view
+            dc.DrawLine(
+                    tabRight + 1,
+                    bottom + 1,
+                    tabRight + 1,
+                    tabTop + 2
+                    );
+            dc.DrawLine(
+                    tabRight + 1,
+                    bottom + 1,
+                    (tabRight - m_view->GetHorizontalTabOffset()),
+                    bottom + 1
+                    );
+        }
+        else
+        {
+            // draw right hand edge of TAB
+            if (tabBelowRight && tabBelowRight->IsSelected())
+            {
+                dc.DrawLine(
+                        tabRight + 1,
+                        (long)(raisedTop - 1),
+                        tabRight + 1,
+                        tabTop + 2
+                        );
+            }
+            else
+            {
+                dc.DrawLine(
+                        tabRight + 1,
+                        top - 1,
+                        tabRight + 1,
+                        tabTop + 2
+                        );
+            }
+        }
+    }
 
-// New HEL version with rounder tabs
-#if 1
-       if (!m_view) return;
-
-       int tabInc   = 0;
-       if (m_isSelected)
-       {
-               tabInc = m_view->GetTabSelectionHeight() - m_view->GetTabHeight();
-       }
-       int tabLeft  = GetX() + m_view->GetViewRect().x;
-       int tabTop   = GetY() + m_view->GetViewRect().y - tabInc;
-       int tabRight = tabLeft + m_view->GetTabWidth();
-       int left     = m_view->GetViewRect().x;
-       int top      = tabTop + m_view->GetTabHeight() + tabInc;
-       int right    = left + m_view->GetViewRect().width;
-       int bottom   = top + m_view->GetViewRect().height;
-
-       if (m_isSelected)
-       {
-               // TAB is selected - draw TAB and the View's full outline
-
-               dc.SetPen(*(m_view->GetHighlightPen()));
-               wxPoint pnts[10];
-               int n = 0;
-               pnts[n].x = left;                       pnts[n++].y = bottom;
-               pnts[n].x = left;                       pnts[n++].y = top;
-               pnts[n].x = tabLeft;            pnts[n++].y = top;
-               pnts[n].x = tabLeft;                    pnts[n++].y = tabTop + 2;
-               pnts[n].x = tabLeft + 2;                pnts[n++].y = tabTop;
-               pnts[n].x = tabRight - 1;       pnts[n++].y = tabTop;
-               dc.DrawLines(n, pnts);
-               if (!lastInRow)
-               {
-                       dc.DrawLine(
-                                       (tabRight + 2),
-                                       top,
-                                       right,
-                                       top
-                                       );
-               }
-
-               dc.SetPen(*(m_view->GetShadowPen()));
-               dc.DrawLine(
-                               tabRight,
-                               tabTop + 2,
-                               tabRight,
-                               top
-                               );
-               dc.DrawLine(
-                               right,
-                               top,
-                               right,
-                               bottom
-                               );
-               dc.DrawLine(
-                               right,
-                               bottom,
-                               left,
-                               bottom
-                               );
-
-               dc.SetPen(*wxBLACK_PEN);
-               dc.DrawPoint(
-                               tabRight,
-                               tabTop + 1
-                               );
-               dc.DrawPoint(
-                               tabRight + 1,
-                               tabTop + 2
-                               );
-               if (lastInRow)
-               {
-                       dc.DrawLine(
-                               tabRight + 1,
-                               bottom,
-                               tabRight + 1,
-                               tabTop + 1
-                               );
-               }
-               else
-               {
-                       dc.DrawLine(
-                               tabRight + 1,
-                               tabTop + 2,
-                               tabRight + 1,
-                               top
-                               );
-                       dc.DrawLine(
-                               right + 1,
-                               top,
-                               right + 1,
-                               bottom + 1
-                               );
-               }
-               dc.DrawLine(
-                               right + 1,
-                               bottom + 1,
-                               left + 1,
-                               bottom + 1
-                               );
-       }
-       else
-       {
-               // TAB is not selected - just draw TAB outline and RH edge
-               // if the TAB is the last in the row
-
-               int maxPositions = ((wxTabLayer*)m_view->GetLayers().Nth(0)->Data())->Number();
-               wxTabControl* tabBelow = 0;
-               wxTabControl* tabBelowRight = 0;
-               if (GetColPosition() > 0)
-               {
-                       tabBelow = m_view->FindTabControlForPosition(
-                                               GetColPosition() - 1,
-                                               GetRowPosition()
-                                               );
-               }
-               if (!lastInRow && GetColPosition() > 0)
-               {
-                       tabBelowRight = m_view->FindTabControlForPosition(
-                                               GetColPosition() - 1,
-                                               GetRowPosition() + 1
-                                               );
-               }
-
-               float raisedTop = top - m_view->GetTabSelectionHeight() +
-                                                       m_view->GetTabHeight();
-
-               dc.SetPen(*(m_view->GetHighlightPen()));
-               wxPoint pnts[10];
-               int n = 0;
-
-               pnts[n].x = tabLeft;
-
-               if (tabBelow && tabBelow->IsSelected())
-               {
-                       pnts[n++].y = (long)raisedTop;
-               }
-               else
-               {
-                       pnts[n++].y = top;
-               }
-               pnts[n].x = tabLeft;                    pnts[n++].y = tabTop + 2;
-               pnts[n].x = tabLeft + 2;                pnts[n++].y = tabTop;
-               pnts[n].x = tabRight - 1;       pnts[n++].y = tabTop;
-               dc.DrawLines(n, pnts);
-
-               dc.SetPen(*(m_view->GetShadowPen()));
-               if (GetRowPosition() >= maxPositions - 1)
-               {
-                       dc.DrawLine(
-                                       tabRight,
-                                       (tabTop + 2),
-                                       tabRight,
-                                       bottom
-                                       );
-                       dc.DrawLine(
-                                       tabRight,
-                                       bottom,
-                                       (tabRight - m_view->GetHorizontalTabOffset()),
-                                       bottom
-                                       );
-               }
-               else
-               {
-                       if (tabBelowRight && tabBelowRight->IsSelected())
-                       {
-                               dc.DrawLine(
-                                               tabRight,
-                                               (long)raisedTop,
-                                               tabRight,
-                                               tabTop + 1
-                                               );
-                       }
-                       else
-                       {
-                               dc.DrawLine(
-                                               tabRight,
-                                               top - 1,
-                                               tabRight,
-                                               tabTop + 1
-                                               );
-                       }
-               }
-
-               dc.SetPen(*wxBLACK_PEN);
-               dc.DrawPoint(
-                               tabRight,
-                               tabTop + 1
-                               );
-               dc.DrawPoint(
-                               tabRight + 1,
-                               tabTop + 2
-                               );
-               if (GetRowPosition() >= maxPositions - 1)
-               {
-                       // draw right hand edge to bottom of view
-                       dc.DrawLine(
-                                       tabRight + 1,
-                                       bottom + 1,
-                                       tabRight + 1,
-                                       tabTop + 2
-                                       );
-                       dc.DrawLine(
-                                       tabRight + 1,
-                                       bottom + 1,
-                                       (tabRight - m_view->GetHorizontalTabOffset()),
-                                       bottom + 1
-                                       );
-               }
-               else
-               {
-                       // draw right hand edge of TAB
-                       if (tabBelowRight && tabBelowRight->IsSelected())
-                       {
-                               dc.DrawLine(
-                                               tabRight + 1,
-                                               (long)(raisedTop - 1),
-                                               tabRight + 1,
-                                               tabTop + 2
-                                               );
-                       }
-                       else
-                       {
-                               dc.DrawLine(
-                                               tabRight + 1,
-                                               top - 1,
-                                               tabRight + 1,
-                                               tabTop + 2
-                                               );
-                       }
-               }
-       }
-
-       // Draw centered text
-       dc.SetPen(*wxBLACK_PEN);
-       if (m_isSelected)
-       {
-               dc.SetFont(*(m_view->GetSelectedTabFont()));
-       }
-       else
-       {
-               dc.SetFont(*(GetFont()));
-       }
-
-       wxColour col(m_view->GetTextColour());
-       dc.SetTextForeground(col);
-       dc.SetBackgroundMode(wxTRANSPARENT);
-       long textWidth, textHeight;
-       dc.GetTextExtent(GetLabel(), &textWidth, &textHeight);
-
-       float textX = (tabLeft + tabRight - textWidth) / 2;
-       float textY = (tabInc + tabTop + m_view->GetVerticalTabTextSpacing());
-       
-       dc.DrawText(GetLabel(), (long)textX, (long)textY);
+    // Draw centered text
+    dc.SetPen(*wxBLACK_PEN);
+    if (m_isSelected)
+    {
+        dc.SetFont(*(m_view->GetSelectedTabFont()));
+    }
+    else
+    {
+        dc.SetFont(*(GetFont()));
+    }
+
+    wxColour col(m_view->GetTextColour());
+    dc.SetTextForeground(col);
+    dc.SetBackgroundMode(wxTRANSPARENT);
+    long textWidth, textHeight;
+    dc.GetTextExtent(GetLabel(), &textWidth, &textHeight);
+
+    float textX = (tabLeft + tabRight - textWidth) / 2;
+    float textY = (tabInc + tabTop + m_view->GetVerticalTabTextSpacing());
+
+    dc.DrawText(GetLabel(), (long)textX, (long)textY);
 #endif
 }
 
@@ -475,7 +495,7 @@ bool wxTabControl::HitTest(int x, int y) const
   // Bottom-right
   int tabX2 = tabX1 + GetWidth();
   int tabY2 = tabY1 + GetHeight();
-  
+
   if (x >= tabX1 && y >= tabY1 && x <= tabX2 && y <= tabY2)
     return TRUE;
   else
@@ -508,16 +528,20 @@ wxTabView::wxTabView(long style)
   m_shadowPen = wxGREY_PEN;
   m_backgroundPen = wxLIGHT_GREY_PEN;
   m_backgroundBrush = wxLIGHT_GREY_BRUSH;
-  m_tabFont = wxTheFontList->FindOrCreateFont(9, wxSWISS, wxNORMAL, wxNORMAL);
-  m_tabSelectedFont = wxTheFontList->FindOrCreateFont(9, wxSWISS, wxNORMAL, wxBOLD);
-  m_window = NULL;
+  m_tabFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+  m_tabSelectedFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+  m_window = (wxWindow *) NULL;
 }
 
 wxTabView::~wxTabView()
 {
+  ClearTabs(TRUE);
 }
-  
+
 // Automatically positions tabs
+// TODO: this should just add the tab to a list, and then
+// a layout function (e.g. Realize) should be called when all tabs have been added.
+// The view rect could easily change as the view window is resized.
 wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *existingTab)
 {
   // First, find which layer we should be adding to.
@@ -545,21 +569,21 @@ wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *exi
     {
       tabLayer = new wxTabLayer;
       m_layers.Append(tabLayer);
-      lastTabNode = NULL;
+      lastTabNode = (wxNode *) NULL;
     }
   }
   int layer = m_layers.Number() - 1;
-  
+
   wxTabControl *tabControl = existingTab;
   if (!existingTab)
     tabControl = OnCreateTabControl();
   tabControl->SetRowPosition(tabLayer->Number());
   tabControl->SetColPosition(layer);
-  
-  wxTabControl *lastTab = NULL;
+
+  wxTabControl *lastTab = (wxTabControl *) NULL;
   if (lastTabNode)
     lastTab = (wxTabControl *)lastTabNode->Data();
-  
+
   // Top of new tab
   int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight());
   // Offset from view top-left
@@ -568,19 +592,93 @@ wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *exi
     horizontalOffset = layer*GetHorizontalTabOffset();
   else
     horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing();
-  
+
   tabControl->SetPosition(horizontalOffset, verticalOffset);
   tabControl->SetSize(GetTabWidth(), GetTabHeight());
   tabControl->SetId(id);
   tabControl->SetLabel(label);
-  tabControl->SetFont(GetTabFont());
-  
+  tabControl->SetFont(GetTabFont());
+
   tabLayer->Append(tabControl);
   m_noTabs ++;
-  
+
   return tabControl;
 }
-  
+
+// Remove the tab without deleting the window
+bool wxTabView::RemoveTab(int id)
+{
+  wxNode *layerNode = m_layers.First();
+  while (layerNode)
+  {
+    wxTabLayer *layer = (wxTabLayer *)layerNode->Data();
+    wxNode *tabNode = layer->First();
+    while (tabNode)
+    {
+      wxTabControl *tab = (wxTabControl *)tabNode->Data();
+      if (tab->GetId() == id)
+      {
+        if (id == m_tabSelection)
+          m_tabSelection = -1;
+        delete tab;
+        delete tabNode;
+        m_noTabs --;
+
+        // The layout has changed
+        LayoutTabs();
+        return TRUE;
+      }
+      tabNode = tabNode->Next();
+    }
+    layerNode = layerNode->Next();
+  }
+  return FALSE;
+}
+
+bool wxTabView::SetTabText(int id, const wxString& label)
+{
+    wxTabControl* control = FindTabControlForId(id);
+    if (!control)
+      return FALSE;
+    control->SetLabel(label);
+    return TRUE;
+}
+
+wxString wxTabView::GetTabText(int id) const
+{
+    wxTabControl* control = FindTabControlForId(id);
+    if (!control)
+      return wxEmptyString;
+    else
+      return control->GetLabel();
+}
+
+// Returns the total height of the tabs component -- this may be several
+// times the height of a tab, if there are several tab layers (rows).
+int wxTabView::GetTotalTabHeight()
+{
+  int minY = 0;
+
+  wxNode *layerNode = m_layers.First();
+  while (layerNode)
+  {
+    wxTabLayer *layer = (wxTabLayer *)layerNode->Data();
+    wxNode *tabNode = layer->First();
+    while (tabNode)
+    {
+      wxTabControl *tab = (wxTabControl *)tabNode->Data();
+
+      if (tab->GetY() < minY)
+        minY = tab->GetY();
+
+      tabNode = tabNode->Next();
+    }
+    layerNode = layerNode->Next();
+  }
+
+  return - minY;
+}
+
 void wxTabView::ClearTabs(bool deleteTabs)
 {
   wxNode *layerNode = m_layers.First();
@@ -602,10 +700,13 @@ void wxTabView::ClearTabs(bool deleteTabs)
     delete layerNode;
     layerNode = nextLayerNode;
   }
+  m_noTabs = 0;
+  m_tabSelection = -1;
 }
-  
+
+
 // Layout tabs (optional, e.g. if resizing window)
-void wxTabView::Layout(void)
+void wxTabView::LayoutTabs(void)
 {
   // Make a list of the tab controls, deleting the wxTabLayers.
   wxList controls;
@@ -628,12 +729,12 @@ void wxTabView::Layout(void)
     delete layerNode;
     layerNode = nextLayerNode;
   }
-  
-  wxTabControl *lastTab = NULL;
-  
+
+  wxTabControl *lastTab = (wxTabControl *) NULL;
+
   wxTabLayer *currentLayer = new wxTabLayer;
   m_layers.Append(currentLayer);
-  
+
   wxNode *node = controls.First();
   while (node)
   {
@@ -651,15 +752,15 @@ void wxTabView::Layout(void)
      {
        currentLayer = new wxTabLayer;
        m_layers.Append(currentLayer);
-       lastTab = NULL;
+       lastTab = (wxTabControl *) NULL;
      }
     }
-    
+
     int layer = m_layers.Number() - 1;
 
     tabControl->SetRowPosition(currentLayer->Number());
     tabControl->SetColPosition(layer);
-  
+
     // Top of new tab
     int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight());
     // Offset from view top-left
@@ -668,7 +769,7 @@ void wxTabView::Layout(void)
       horizontalOffset = layer*GetHorizontalTabOffset();
     else
       horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing();
-  
+
     tabControl->SetPosition(horizontalOffset, verticalOffset);
     tabControl->SetSize(GetTabWidth(), GetTabHeight());
 
@@ -688,91 +789,100 @@ void wxTabView::Layout(void)
 // Draw all tabs
 void wxTabView::Draw(wxDC& dc)
 {
-       // Draw top margin area (beneath tabs and above view area)
-       if (GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
-       {
-               dc.SetPen(*wxTRANSPARENT_PEN);
-               dc.SetBrush(*GetBackgroundBrush());
-
-               // Add 1 because the pen is transparent. Under Motif, may be different.
-               dc.DrawRectangle(
-                               m_tabViewRect.x,
-                               (m_tabViewRect.y - m_topMargin),
-                               (m_tabViewRect.width + 1),
-                               (m_topMargin + 1)
-                               );
-       }
-
-       // Draw layers in reverse order
-       wxNode *node = m_layers.Last();
-       while (node)
-       {
-               wxTabLayer *layer = (wxTabLayer *)node->Data();
-               wxNode *node2 = layer->First();
-               while (node2)
-               {
-                       wxTabControl *control = (wxTabControl *)node2->Data();
-                       control->OnDraw(dc, (node2->Next() == NULL));
-                       node2 = node2->Next();
-               }
-
-               node = node->Previous();
-       }
-
-
-#if 0
-       if (GetTabStyle() & wxTAB_STYLE_DRAW_BOX)
-       {
-               dc.SetPen(GetShadowPen());
-
-               // Draw bottom line
-               dc.DrawLine(
-                               (GetViewRect().x + 1),
-                               (GetViewRect().y + GetViewRect().height),
-                               (GetViewRect().x + GetViewRect().width),
-                               (GetViewRect().y + GetViewRect().height)
-                               );
-
-               // Draw right line
-               dc.DrawLine(
-                               (GetViewRect().x + GetViewRect().width),
-                               (GetViewRect().y - GetTopMargin() + 1),
-                               (GetViewRect().x + GetViewRect().width),
-                               (GetViewRect().y + GetViewRect().height)
-                               );
-
-               dc.SetPen(wxBLACK_PEN);
-
-               // Draw bottom line
-               dc.DrawLine(
-                               (GetViewRect().x),
-                               (GetViewRect().y + GetViewRect().height + 1),
-                               (GetViewRect().x + GetViewRect().width),
-                               (GetViewRect().y + GetViewRect().height + 1)
-                               );
-
-               // Draw right line
-               dc.DrawLine(
-                               (GetViewRect().x + GetViewRect().width + 1),
-                               (GetViewRect().y - GetTopMargin()),
-                               (GetViewRect().x + GetViewRect().width + 1),
-                               (GetViewRect().y + GetViewRect().height + 1)
-                               );
-       }
+        // Don't draw anything if there are no tabs.
+        if (GetNumberOfTabs() == 0)
+          return;
+
+    // Draw top margin area (beneath tabs and above view area)
+    if (GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
+    {
+        dc.SetPen(*wxTRANSPARENT_PEN);
+        dc.SetBrush(*GetBackgroundBrush());
+
+        // Add 1 because the pen is transparent. Under Motif, may be different.
+        dc.DrawRectangle(
+                m_tabViewRect.x,
+                (m_tabViewRect.y - m_topMargin),
+                (m_tabViewRect.width + 1),
+                (m_topMargin + 1)
+                );
+    }
+
+    // Draw layers in reverse order
+    wxNode *node = m_layers.Last();
+    while (node)
+    {
+        wxTabLayer *layer = (wxTabLayer *)node->Data();
+        wxNode *node2 = layer->First();
+        while (node2)
+        {
+            wxTabControl *control = (wxTabControl *)node2->Data();
+            control->OnDraw(dc, (node2->Next() == NULL));
+            node2 = node2->Next();
+        }
+
+        node = node->Previous();
+    }
+
+
+#ifndef wxUSE_NEW_METHOD
+    if (GetTabStyle() & wxTAB_STYLE_DRAW_BOX)
+    {
+        dc.SetPen(* GetShadowPen());
+
+        // Draw bottom line
+        dc.DrawLine(
+                (GetViewRect().x + 1),
+                (GetViewRect().y + GetViewRect().height),
+                (GetViewRect().x + GetViewRect().width + 1),
+                (GetViewRect().y + GetViewRect().height)
+                );
+
+        // Draw right line
+        dc.DrawLine(
+                (GetViewRect().x + GetViewRect().width),
+                (GetViewRect().y - GetTopMargin() + 1),
+                (GetViewRect().x + GetViewRect().width),
+                (GetViewRect().y + GetViewRect().height)
+                );
+
+        dc.SetPen(* wxBLACK_PEN);
+
+        // Draw bottom line
+        dc.DrawLine(
+                (GetViewRect().x),
+                (GetViewRect().y + GetViewRect().height + 1),
+#if defined(__WXMOTIF__)
+                (GetViewRect().x + GetViewRect().width + 1),
+#else
+                (GetViewRect().x + GetViewRect().width + 2),
+#endif
+
+                (GetViewRect().y + GetViewRect().height + 1)
+                );
+
+        // Draw right line
+        dc.DrawLine(
+                (GetViewRect().x + GetViewRect().width + 1),
+                (GetViewRect().y - GetTopMargin()),
+                (GetViewRect().x + GetViewRect().width + 1),
+                (GetViewRect().y + GetViewRect().height + 1)
+                );
+    }
 #endif
 }
-  
+
 // Process mouse event, return FALSE if we didn't process it
 bool wxTabView::OnEvent(wxMouseEvent& event)
 {
   if (!event.LeftDown())
     return FALSE;
-    
-  float x, y;
-  event.Position(&x, &y);
-  
-  wxTabControl *hitControl = NULL;
-  
+
+  wxCoord x, y;
+  event.GetPosition(&x, &y);
+
+  wxTabControl *hitControl = (wxTabControl *) NULL;
+
   wxNode *node = m_layers.First();
   while (node)
   {
@@ -784,27 +894,27 @@ bool wxTabView::OnEvent(wxMouseEvent& event)
       if (control->HitTest((int)x, (int)y))
       {
         hitControl = control;
-        node = NULL;
-        node2 = NULL;
+        node = (wxNode *) NULL;
+        node2 = (wxNode *) NULL;
       }
       else
         node2 = node2->Next();
     }
-  
+
     if (node)
       node = node->Next();
   }
-  
+
   if (!hitControl)
     return FALSE;
-    
+
   wxTabControl *currentTab = FindTabControlForId(m_tabSelection);
-    
+
   if (hitControl == currentTab)
     return FALSE;
-    
+
   ChangeTab(hitControl);
-  
+
   return TRUE;
 }
 
@@ -814,13 +924,13 @@ bool wxTabView::ChangeTab(wxTabControl *control)
   int oldTab = -1;
   if (currentTab)
     oldTab = currentTab->GetId();
-  
+
   if (control == currentTab)
     return TRUE;
-    
+
   if (m_layers.Number() == 0)
     return FALSE;
-    
+
   if (!OnTabPreActivate(control->GetId(), oldTab))
     return FALSE;
 
@@ -829,12 +939,12 @@ bool wxTabView::ChangeTab(wxTabControl *control)
 
   if (currentTab)
     currentTab->SetSelected(FALSE);
-    
+
   control->SetSelected(TRUE);
   m_tabSelection = control->GetId();
 
   OnTabActivate(control->GetId(), oldTab);
-  
+
   // Leave window refresh for the implementing window
 
   return TRUE;
@@ -846,9 +956,9 @@ bool wxTabView::MoveSelectionTab(wxTabControl *control)
 {
   if (m_layers.Number() == 0)
     return FALSE;
-    
+
   wxTabLayer *firstLayer = (wxTabLayer *)m_layers.First()->Data();
-    
+
   // Find what column this tab is at, so we can swap with the one at the bottom.
   // If we're on the bottom layer, then no need to swap.
   if (!firstLayer->Member(control))
@@ -861,29 +971,29 @@ bool wxTabView::MoveSelectionTab(wxTabControl *control)
     wxNode *otherNode = firstLayer->Nth(col);
     if (!otherNode)
       return FALSE;
-      
+
     // If this is already in the bottom layer, return now
     if (otherNode == thisNode)
       return TRUE;
-      
+
     wxTabControl *otherTab = (wxTabControl *)otherNode->Data();
-     
+
     // We now have pointers to the tab to be changed to,
     // and the tab on the first layer. Swap tab structures and
     // position details.
-     
+
     int thisX = control->GetX();
     int thisY = control->GetY();
     int thisColPos = control->GetColPosition();
     int otherX = otherTab->GetX();
     int otherY = otherTab->GetY();
     int otherColPos = otherTab->GetColPosition();
-     
+
     control->SetPosition(otherX, otherY);
     control->SetColPosition(otherColPos);
     otherTab->SetPosition(thisX, thisY);
     otherTab->SetColPosition(thisColPos);
-     
+
     // Swap the data for the nodes
     thisNode->SetData(otherTab);
     otherNode->SetData(control);
@@ -895,7 +1005,7 @@ bool wxTabView::MoveSelectionTab(wxTabControl *control)
 void wxTabView::OnTabActivate(int /*activateId*/, int /*deactivateId*/)
 {
 }
-  
+
 void wxTabView::SetHighlightColour(const wxColour& col)
 {
   m_highlightColour = col;
@@ -917,23 +1027,32 @@ void wxTabView::SetBackgroundColour(const wxColour& col)
 
 void wxTabView::SetTabSelection(int sel, bool activateTool)
 {
+  if ( sel==m_tabSelection )
+    return;
+
   int oldSel = m_tabSelection;
   wxTabControl *control = FindTabControlForId(sel);
+  wxTabControl *oldControl = FindTabControlForId(m_tabSelection);
 
   if (!OnTabPreActivate(sel, oldSel))
     return;
-    
+
   if (control)
-    control->SetSelected((sel != 0)); // TODO ??
-  else
+    control->SetSelected((sel != -1)); // TODO ??
+  else if (sel != -1)
   {
-    wxMessageBox(_("Could not find tab for id"), _("Error"), wxOK);
+    wxFAIL_MSG(_("Could not find tab for id"));
     return;
   }
-    
+
+  if (oldControl)
+    oldControl->SetSelected(FALSE);
+
   m_tabSelection = sel;
-  MoveSelectionTab(control);
-  
+
+  if (control)
+    MoveSelectionTab(control);
+
   if (activateTool)
     OnTabActivate(sel, oldSel);
 }
@@ -955,7 +1074,7 @@ wxTabControl *wxTabView::FindTabControlForId(int id) const
     }
     node1 = node1->Next();
   }
-  return NULL;
+  return (wxTabControl *) NULL;
 }
 
 // Find tab control for layer, position (starting from zero)
@@ -963,11 +1082,11 @@ wxTabControl *wxTabView::FindTabControlForPosition(int layer, int position) cons
 {
   wxNode *node1 = m_layers.Nth(layer);
   if (!node1)
-    return NULL;
+    return (wxTabControl *) NULL;
   wxTabLayer *tabLayer = (wxTabLayer *)node1->Data();
   wxNode *node2 = tabLayer->Nth(position);
   if (!node2)
-    return NULL;
+    return (wxTabControl *) NULL;
   return (wxTabControl *)node2->Data();
 }
 
@@ -993,7 +1112,7 @@ wxNode *wxTabView::FindTabNodeAndColumn(wxTabControl *control, int *col) const
     }
     node1 = node1->Next();
   }
-  return NULL;
+  return (wxNode *) NULL;
 }
 
 int wxTabView::CalculateTabWidth(int noTabs, bool adjustView)
@@ -1009,7 +1128,7 @@ int wxTabView::CalculateTabWidth(int noTabs, bool adjustView)
 /*
  * wxTabbedDialog
  */
+
 IMPLEMENT_CLASS(wxTabbedDialog, wxDialog)
 
 BEGIN_EVENT_TABLE(wxTabbedDialog, wxDialog)
@@ -1024,7 +1143,7 @@ wxTabbedDialog::wxTabbedDialog(wxWindow *parent, wxWindowID id,
     long windowStyle, const wxString& name):
    wxDialog(parent, id, title, pos, size, windowStyle, name)
 {
-  m_tabView = NULL;
+  m_tabView = (wxTabView *) NULL;
 }
 
 wxTabbedDialog::~wxTabbedDialog(void)
@@ -1032,7 +1151,7 @@ wxTabbedDialog::~wxTabbedDialog(void)
   if (m_tabView)
     delete m_tabView;
 }
+
 void wxTabbedDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event) )
 {
   Destroy();
@@ -1054,7 +1173,7 @@ void wxTabbedDialog::OnPaint(wxPaintEvent& WXUNUSED(event) )
 /*
  * wxTabbedPanel
  */
+
 IMPLEMENT_CLASS(wxTabbedPanel, wxPanel)
 
 BEGIN_EVENT_TABLE(wxTabbedPanel, wxPanel)
@@ -1066,14 +1185,14 @@ wxTabbedPanel::wxTabbedPanel(wxWindow *parent, wxWindowID id, const wxPoint& pos
    const wxSize& size, long windowStyle, const wxString& name):
    wxPanel(parent, id, pos, size, windowStyle, name)
 {
-  m_tabView = NULL;
+  m_tabView = (wxTabView *) NULL;
 }
 
 wxTabbedPanel::~wxTabbedPanel(void)
 {
   delete m_tabView;
 }
+
 void wxTabbedPanel::OnMouseEvent(wxMouseEvent& event)
 {
   if (m_tabView)
@@ -1088,15 +1207,15 @@ void wxTabbedPanel::OnPaint(wxPaintEvent& WXUNUSED(event) )
 }
 
 /*
- * wxDialogTabView
+ * wxPanelTabView
  */
+
 IMPLEMENT_CLASS(wxPanelTabView, wxTabView)
+
 wxPanelTabView::wxPanelTabView(wxPanel *pan, long style): wxTabView(style), m_tabWindows(wxKEY_INTEGER)
 {
   m_panel = pan;
-  m_currentWindow = NULL;
+  m_currentWindow = (wxWindow *) NULL;
 
   if (m_panel->IsKindOf(CLASSINFO(wxTabbedDialog)))
     ((wxTabbedDialog *)m_panel)->SetTabView(this);
@@ -1116,7 +1235,7 @@ void wxPanelTabView::OnTabActivate(int activateId, int deactivateId)
 {
   if (!m_panel)
     return;
-    
+
   wxWindow *oldWindow = ((deactivateId == -1) ? 0 : GetTabWindow(deactivateId));
   wxWindow *newWindow = GetTabWindow(activateId);
 
@@ -1124,11 +1243,11 @@ void wxPanelTabView::OnTabActivate(int activateId, int deactivateId)
     oldWindow->Show(FALSE);
   if (newWindow)
     newWindow->Show(TRUE);
-    
+
   m_panel->Refresh();
 }
 
-   
+
 void wxPanelTabView::AddTabWindow(int id, wxWindow *window)
 {
   m_tabWindows.Append((long)id, window);
@@ -1139,8 +1258,8 @@ wxWindow *wxPanelTabView::GetTabWindow(int id) const
 {
   wxNode *node = m_tabWindows.Find((long)id);
   if (!node)
-    return NULL;
-  return (wxWindow *)node->Data();    
+    return (wxWindow *) NULL;
+  return (wxWindow *)node->Data();
 }
 
 void wxPanelTabView::ClearWindows(bool deleteWindows)
@@ -1162,3 +1281,4 @@ void wxPanelTabView::ShowWindowForTab(int id)
   newWindow->Refresh();
 }
 
+#endif // wxUSE_TAB_DIALOG