]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/tabg.cpp
Added Property List classes to main library; added proplist sample; merged
[wxWidgets.git] / src / generic / tabg.cpp
index 20e96214c016ba826f6ccb4aac7d9dcf2b310c93..297d93d55e382a38195213ecb9dba2a90f79a742 100644 (file)
 
 #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 +43,6 @@ wxTabControl::wxTabControl(wxTabView *v)
 {
   m_view = v;
   m_isSelected = FALSE;
-  m_labelFont = NULL;
   m_offsetX = 0;
   m_offsetY = 0;
   m_width = 0;
@@ -56,7 +59,7 @@ 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;
     
@@ -70,23 +73,27 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
   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 +114,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 +133,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);
 
@@ -145,13 +152,17 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
       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,12 +177,16 @@ 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));
     }
@@ -181,23 +196,27 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
   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,10 +226,9 @@ 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
 
-// New HEL version with rounder tabs
-#if 1
        if (!m_view) return;
 
        int tabInc   = 0;
@@ -508,16 +526,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::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
+  m_tabSelectedFont = wxSystemSettings::GetSystemFont(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,7 +567,7 @@ 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;
@@ -556,7 +578,7 @@ wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *exi
   tabControl->SetRowPosition(tabLayer->Number());
   tabControl->SetColPosition(layer);
   
-  wxTabControl *lastTab = NULL;
+  wxTabControl *lastTab = (wxTabControl *) NULL;
   if (lastTabNode)
     lastTab = (wxTabControl *)lastTabNode->Data();
   
@@ -573,14 +595,88 @@ wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *exi
   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
+        Layout();
+        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,8 +698,10 @@ void wxTabView::ClearTabs(bool deleteTabs)
     delete layerNode;
     layerNode = nextLayerNode;
   }
+  m_noTabs = 0;
 }
-  
+
+
 // Layout tabs (optional, e.g. if resizing window)
 void wxTabView::Layout(void)
 {
@@ -629,7 +727,7 @@ void wxTabView::Layout(void)
     layerNode = nextLayerNode;
   }
   
-  wxTabControl *lastTab = NULL;
+  wxTabControl *lastTab = (wxTabControl *) NULL;
   
   wxTabLayer *currentLayer = new wxTabLayer;
   m_layers.Append(currentLayer);
@@ -651,7 +749,7 @@ void wxTabView::Layout(void)
      {
        currentLayer = new wxTabLayer;
        m_layers.Append(currentLayer);
-       lastTab = NULL;
+       lastTab = (wxTabControl *) NULL;
      }
     }
     
@@ -688,6 +786,10 @@ void wxTabView::Layout(void)
 // Draw all tabs
 void wxTabView::Draw(wxDC& dc)
 {
+        // 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)
        {
@@ -720,16 +822,16 @@ void wxTabView::Draw(wxDC& dc)
        }
 
 
-#if 0
+#ifndef wxUSE_NEW_METHOD
        if (GetTabStyle() & wxTAB_STYLE_DRAW_BOX)
        {
-               dc.SetPen(GetShadowPen());
+               dc.SetPen(GetShadowPen());
 
                // Draw bottom line
                dc.DrawLine(
                                (GetViewRect().x + 1),
                                (GetViewRect().y + GetViewRect().height),
-                               (GetViewRect().x + GetViewRect().width),
+                               (GetViewRect().x + GetViewRect().width + 1),
                                (GetViewRect().y + GetViewRect().height)
                                );
 
@@ -741,13 +843,18 @@ void wxTabView::Draw(wxDC& dc)
                                (GetViewRect().y + GetViewRect().height)
                                );
 
-               dc.SetPen(wxBLACK_PEN);
+               dc.SetPen(wxBLACK_PEN);
 
                // Draw bottom line
                dc.DrawLine(
                                (GetViewRect().x),
                                (GetViewRect().y + GetViewRect().height + 1),
-                               (GetViewRect().x + GetViewRect().width),
+#if defined(__WXMOTIF__)
+                               (GetViewRect().x + GetViewRect().width + 1),
+#else
+                               (GetViewRect().x + GetViewRect().width + 2),
+#endif
+
                                (GetViewRect().y + GetViewRect().height + 1)
                                );
 
@@ -771,7 +878,7 @@ bool wxTabView::OnEvent(wxMouseEvent& event)
   float x, y;
   event.Position(&x, &y);
   
-  wxTabControl *hitControl = NULL;
+  wxTabControl *hitControl = (wxTabControl *) NULL;
   
   wxNode *node = m_layers.First();
   while (node)
@@ -784,8 +891,8 @@ 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();
@@ -919,20 +1026,26 @@ void wxTabView::SetTabSelection(int sel, bool activateTool)
 {
   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 +1068,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 +1076,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 +1106,7 @@ wxNode *wxTabView::FindTabNodeAndColumn(wxTabControl *control, int *col) const
     }
     node1 = node1->Next();
   }
-  return NULL;
+  return (wxNode *) NULL;
 }
 
 int wxTabView::CalculateTabWidth(int noTabs, bool adjustView)
@@ -1024,7 +1137,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)
@@ -1066,7 +1179,7 @@ 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)
@@ -1088,7 +1201,7 @@ void wxTabbedPanel::OnPaint(wxPaintEvent& WXUNUSED(event) )
 }
 
 /*
- * wxDialogTabView
+ * wxPanelTabView
  */
  
 IMPLEMENT_CLASS(wxPanelTabView, wxTabView)
@@ -1096,7 +1209,7 @@ 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);
@@ -1139,7 +1252,7 @@ wxWindow *wxPanelTabView::GetTabWindow(int id) const
 {
   wxNode *node = m_tabWindows.Find((long)id);
   if (!node)
-    return NULL;
+    return (wxWindow *) NULL;
   return (wxWindow *)node->Data();    
 }