home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / generic / tabg.cpp < prev    next >
C/C++ Source or Header  |  2002-01-08  |  36KB  |  1,285 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        tabg.cpp
  3. // Purpose:     Generic tabbed dialogs
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     01/02/97
  7. // RCS-ID:      $Id: tabg.cpp,v 1.15 2002/01/08 23:52:54 VS Exp $
  8. // Copyright:   (c)
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13. #pragma implementation "tabg.h"
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22.  
  23. #if wxUSE_TAB_DIALOG
  24.  
  25. #ifndef WX_PRECOMP
  26. #include "wx/wx.h"
  27. #endif
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <stdarg.h>
  32. #include <math.h>
  33.  
  34. #include "wx/tab.h"
  35.  
  36. // not defined: use old, square tab implementation (fills in tabs)
  37. // defined: use new, rounded tab implementation (doesn't colour in tabs)
  38. // #define wxUSE_NEW_METHOD
  39.  
  40. IMPLEMENT_DYNAMIC_CLASS(wxTabControl, wxObject)
  41.  
  42. IMPLEMENT_DYNAMIC_CLASS(wxTabLayer, wxList)
  43.  
  44. wxTabControl::wxTabControl(wxTabView *v)
  45. {
  46.   m_view = v;
  47.   m_isSelected = FALSE;
  48.   m_offsetX = 0;
  49.   m_offsetY = 0;
  50.   m_width = 0;
  51.   m_height = 0;
  52.   m_id = 0;
  53.   m_rowPosition = 0;
  54.   m_colPosition = 0;
  55. }
  56.  
  57. wxTabControl::~wxTabControl(void)
  58. {
  59. }
  60.  
  61. void wxTabControl::OnDraw(wxDC& dc, bool lastInRow)
  62. {
  63.     // Old, but in some ways better (drawing opaque tabs)
  64. #ifndef wxUSE_NEW_METHOD
  65.   if (!m_view)
  66.     return;
  67.  
  68.   // Top-left of tab view area
  69.   int viewX = m_view->GetViewRect().x;
  70.   int viewY = m_view->GetViewRect().y;
  71.  
  72.   // Top-left of tab control
  73.   int tabX = GetX() + viewX;
  74.   int tabY = GetY() + viewY;
  75.   int tabHeightInc = 0;
  76.   if (m_isSelected)
  77.   {
  78.     tabHeightInc = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());
  79.     tabY -= tabHeightInc;
  80.   }
  81.  
  82.   dc.SetPen(*wxTRANSPARENT_PEN);
  83.  
  84.   // Draw grey background
  85.   if (m_view->GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
  86.   {
  87.     dc.SetBrush(*m_view->GetBackgroundBrush());
  88.  
  89.     // Add 1 because the pen is transparent. Under Motif, may be different.
  90. #ifdef __WXMOTIF__
  91.     dc.DrawRectangle(tabX, tabY, (GetWidth()+1), (GetHeight() + tabHeightInc));
  92. #else
  93.     dc.DrawRectangle(tabX, tabY, (GetWidth()+1), (GetHeight() + 1 + tabHeightInc));
  94. #endif
  95.   }
  96.  
  97.   // Draw highlight and shadow
  98.   dc.SetPen(*m_view->GetHighlightPen());
  99.  
  100.   // Calculate the top of the tab beneath. It's the height of the tab, MINUS
  101.   // a bit if the tab below happens to be selected. Check.
  102.   wxTabControl *tabBeneath = NULL;
  103.   int subtractThis = 0;
  104.   if (GetColPosition() > 0)
  105.     tabBeneath = m_view->FindTabControlForPosition(GetColPosition() - 1, GetRowPosition());
  106.   if (tabBeneath && tabBeneath->IsSelected())
  107.     subtractThis = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());
  108.  
  109.   // Vertical highlight: if first tab, draw to bottom of view
  110.   if (tabX == m_view->GetViewRect().x && (m_view->GetTabStyle() & wxTAB_STYLE_DRAW_BOX))
  111.     dc.DrawLine(tabX, tabY, tabX, (m_view->GetViewRect().y + m_view->GetViewRect().height));
  112.   else if (tabX == m_view->GetViewRect().x)
  113.     // Not box drawing, just to top of view.
  114.     dc.DrawLine(tabX, tabY, tabX, (m_view->GetViewRect().y));
  115.   else
  116.     dc.DrawLine(tabX, tabY, tabX, (tabY + GetHeight() + tabHeightInc - subtractThis));
  117.  
  118.   dc.DrawLine(tabX, tabY, (tabX + GetWidth()), tabY);
  119.   dc.SetPen(*m_view->GetShadowPen());
  120.  
  121.   // Test if we're outside the right-hand edge of the view area
  122.   if (((tabX + GetWidth()) >= m_view->GetViewRect().x + m_view->GetViewRect().width) && (m_view->GetTabStyle() & wxTAB_STYLE_DRAW_BOX))
  123.   {
  124.     int bottomY = m_view->GetViewRect().y + m_view->GetViewRect().height + GetY() + m_view->GetTabHeight() + m_view->GetTopMargin();
  125.     // Add a tab height since we wish to draw to the bottom of the view.
  126.     dc.DrawLine((tabX + GetWidth()), tabY,
  127.       (tabX + GetWidth()), bottomY);
  128.  
  129.     // Calculate the far-right of the view, since we don't wish to
  130.     // draw inside that
  131.     int rightOfView = m_view->GetViewRect().x + m_view->GetViewRect().width + 1;
  132.  
  133.     // Draw the horizontal bit to connect to the view rectangle
  134.     dc.DrawLine((wxMax((tabX + GetWidth() - m_view->GetHorizontalTabOffset()), rightOfView)), (bottomY-1),
  135.       (tabX + GetWidth()), (bottomY-1));
  136.  
  137.     // Draw black line to emphasize shadow
  138.     dc.SetPen(*wxBLACK_PEN);
  139.     dc.DrawLine((tabX + GetWidth() + 1), (tabY+1),
  140.       (tabX + GetWidth() + 1), bottomY);
  141.  
  142.     // Draw the horizontal bit to connect to the view rectangle
  143.     dc.DrawLine((wxMax((tabX + GetWidth() - m_view->GetHorizontalTabOffset()), rightOfView)), (bottomY),
  144.       (tabX + GetWidth() + 1), (bottomY));
  145.   }
  146.   else
  147.   {
  148.     if (lastInRow)
  149.     {
  150.       // 25/5/97 UNLESS it's less than the max number of positions in this row
  151.  
  152.       int topY = m_view->GetViewRect().y - m_view->GetTopMargin();
  153.  
  154.       int maxPositions = ((wxTabLayer *)m_view->GetLayers().Nth(0)->Data())->Number();
  155.  
  156.       // Only down to the bottom of the tab, not to the top of the view
  157.       if ( GetRowPosition() < (maxPositions - 1) )
  158.         topY = tabY + GetHeight() + tabHeightInc;
  159.  
  160. #ifdef __WXMOTIF__
  161.       topY -= 1;
  162. #endif
  163.  
  164.       // Shadow
  165.       dc.DrawLine((tabX + GetWidth()), tabY, (tabX + GetWidth()), topY);
  166.       // Draw black line to emphasize shadow
  167.       dc.SetPen(*wxBLACK_PEN);
  168.       dc.DrawLine((tabX + GetWidth() + 1), (tabY+1), (tabX + GetWidth() + 1),
  169.          topY);
  170.     }
  171.     else
  172.     {
  173.       // Calculate the top of the tab beneath. It's the height of the tab, MINUS
  174.       // a bit if the tab below (and next col along) happens to be selected. Check.
  175.       wxTabControl *tabBeneath = NULL;
  176.       int subtractThis = 0;
  177.       if (GetColPosition() > 0)
  178.         tabBeneath = m_view->FindTabControlForPosition(GetColPosition() - 1, GetRowPosition() + 1);
  179.       if (tabBeneath && tabBeneath->IsSelected())
  180.         subtractThis = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight());
  181.  
  182. #ifdef __WXMOTIF__
  183.       subtractThis += 1;
  184. #endif
  185.  
  186.       // Draw only to next tab down.
  187.       dc.DrawLine((tabX + GetWidth()), tabY,
  188.          (tabX + GetWidth()), (tabY + GetHeight() + tabHeightInc - subtractThis));
  189.  
  190.       // Draw black line to emphasize shadow
  191.       dc.SetPen(*wxBLACK_PEN);
  192.       dc.DrawLine((tabX + GetWidth() + 1), (tabY+1), (tabX + GetWidth() + 1),
  193.          (tabY + GetHeight() + tabHeightInc - subtractThis));
  194.     }
  195.   }
  196.  
  197.   // Draw centered text
  198.   int textY = tabY + m_view->GetVerticalTabTextSpacing() + tabHeightInc;
  199.  
  200.   if (m_isSelected)
  201.     dc.SetFont(* m_view->GetSelectedTabFont());
  202.   else
  203.     dc.SetFont(* GetFont());
  204.  
  205.   wxColour col(m_view->GetTextColour());
  206.   dc.SetTextForeground(col);
  207.   dc.SetBackgroundMode(wxTRANSPARENT);
  208.   long textWidth, textHeight;
  209.   dc.GetTextExtent(GetLabel(), &textWidth, &textHeight);
  210.  
  211.   int textX = (int)(tabX + (GetWidth() - textWidth)/2.0);
  212.   if (textX < (tabX + 2))
  213.     textX = (tabX + 2);
  214.  
  215.   dc.SetClippingRegion(tabX, tabY, GetWidth(), GetHeight());
  216.   dc.DrawText(GetLabel(), textX, textY);
  217.   dc.DestroyClippingRegion();
  218.  
  219.   if (m_isSelected)
  220.   {
  221.     dc.SetPen(*m_view->GetHighlightPen());
  222.  
  223.     // Draw white highlight from the tab's left side to the left hand edge of the view
  224.     dc.DrawLine(m_view->GetViewRect().x, (tabY + GetHeight() + tabHeightInc),
  225.      tabX, (tabY + GetHeight() + tabHeightInc));
  226.  
  227.     // Draw white highlight from the tab's right side to the right hand edge of the view
  228.     dc.DrawLine((tabX + GetWidth()), (tabY + GetHeight() + tabHeightInc),
  229.      m_view->GetViewRect().x + m_view->GetViewRect().width, (tabY + GetHeight() + tabHeightInc));
  230.   }
  231. #else
  232.     // New HEL version with rounder tabs
  233.  
  234.     if (!m_view) return;
  235.  
  236.     int tabInc   = 0;
  237.     if (m_isSelected)
  238.     {
  239.         tabInc = m_view->GetTabSelectionHeight() - m_view->GetTabHeight();
  240.     }
  241.     int tabLeft  = GetX() + m_view->GetViewRect().x;
  242.     int tabTop   = GetY() + m_view->GetViewRect().y - tabInc;
  243.     int tabRight = tabLeft + m_view->GetTabWidth();
  244.     int left     = m_view->GetViewRect().x;
  245.     int top      = tabTop + m_view->GetTabHeight() + tabInc;
  246.     int right    = left + m_view->GetViewRect().width;
  247.     int bottom   = top + m_view->GetViewRect().height;
  248.  
  249.     if (m_isSelected)
  250.     {
  251.         // TAB is selected - draw TAB and the View's full outline
  252.  
  253.         dc.SetPen(*(m_view->GetHighlightPen()));
  254.         wxPoint pnts[10];
  255.         int n = 0;
  256.         pnts[n].x = left;            pnts[n++].y = bottom;
  257.         pnts[n].x = left;             pnts[n++].y = top;
  258.         pnts[n].x = tabLeft;         pnts[n++].y = top;
  259.         pnts[n].x = tabLeft;            pnts[n++].y = tabTop + 2;
  260.         pnts[n].x = tabLeft + 2;        pnts[n++].y = tabTop;
  261.         pnts[n].x = tabRight - 1;    pnts[n++].y = tabTop;
  262.         dc.DrawLines(n, pnts);
  263.         if (!lastInRow)
  264.         {
  265.             dc.DrawLine(
  266.                     (tabRight + 2),
  267.                     top,
  268.                     right,
  269.                     top
  270.                     );
  271.         }
  272.  
  273.         dc.SetPen(*(m_view->GetShadowPen()));
  274.         dc.DrawLine(
  275.                 tabRight,
  276.                 tabTop + 2,
  277.                 tabRight,
  278.                 top
  279.                 );
  280.         dc.DrawLine(
  281.                 right,
  282.                 top,
  283.                 right,
  284.                 bottom
  285.                 );
  286.         dc.DrawLine(
  287.                 right,
  288.                 bottom,
  289.                 left,
  290.                 bottom
  291.                 );
  292.  
  293.         dc.SetPen(*wxBLACK_PEN);
  294.         dc.DrawPoint(
  295.                 tabRight,
  296.                 tabTop + 1
  297.                 );
  298.         dc.DrawPoint(
  299.                 tabRight + 1,
  300.                 tabTop + 2
  301.                 );
  302.         if (lastInRow)
  303.         {
  304.             dc.DrawLine(
  305.                 tabRight + 1,
  306.                 bottom,
  307.                 tabRight + 1,
  308.                 tabTop + 1
  309.                 );
  310.         }
  311.         else
  312.         {
  313.             dc.DrawLine(
  314.                 tabRight + 1,
  315.                 tabTop + 2,
  316.                 tabRight + 1,
  317.                 top
  318.                 );
  319.             dc.DrawLine(
  320.                 right + 1,
  321.                 top,
  322.                 right + 1,
  323.                 bottom + 1
  324.                 );
  325.         }
  326.         dc.DrawLine(
  327.                 right + 1,
  328.                 bottom + 1,
  329.                 left + 1,
  330.                 bottom + 1
  331.                 );
  332.     }
  333.     else
  334.     {
  335.         // TAB is not selected - just draw TAB outline and RH edge
  336.         // if the TAB is the last in the row
  337.  
  338.         int maxPositions = ((wxTabLayer*)m_view->GetLayers().Nth(0)->Data())->Number();
  339.         wxTabControl* tabBelow = 0;
  340.         wxTabControl* tabBelowRight = 0;
  341.         if (GetColPosition() > 0)
  342.         {
  343.             tabBelow = m_view->FindTabControlForPosition(
  344.                         GetColPosition() - 1,
  345.                         GetRowPosition()
  346.                         );
  347.         }
  348.         if (!lastInRow && GetColPosition() > 0)
  349.         {
  350.             tabBelowRight = m_view->FindTabControlForPosition(
  351.                         GetColPosition() - 1,
  352.                         GetRowPosition() + 1
  353.                         );
  354.         }
  355.  
  356.         float raisedTop = top - m_view->GetTabSelectionHeight() +
  357.                             m_view->GetTabHeight();
  358.  
  359.         dc.SetPen(*(m_view->GetHighlightPen()));
  360.         wxPoint pnts[10];
  361.         int n = 0;
  362.  
  363.         pnts[n].x = tabLeft;
  364.  
  365.         if (tabBelow && tabBelow->IsSelected())
  366.         {
  367.             pnts[n++].y = (long)raisedTop;
  368.         }
  369.         else
  370.         {
  371.             pnts[n++].y = top;
  372.         }
  373.         pnts[n].x = tabLeft;            pnts[n++].y = tabTop + 2;
  374.         pnts[n].x = tabLeft + 2;        pnts[n++].y = tabTop;
  375.         pnts[n].x = tabRight - 1;    pnts[n++].y = tabTop;
  376.         dc.DrawLines(n, pnts);
  377.  
  378.         dc.SetPen(*(m_view->GetShadowPen()));
  379.         if (GetRowPosition() >= maxPositions - 1)
  380.         {
  381.             dc.DrawLine(
  382.                     tabRight,
  383.                     (tabTop + 2),
  384.                     tabRight,
  385.                     bottom
  386.                     );
  387.             dc.DrawLine(
  388.                     tabRight,
  389.                     bottom,
  390.                     (tabRight - m_view->GetHorizontalTabOffset()),
  391.                     bottom
  392.                     );
  393.         }
  394.         else
  395.         {
  396.             if (tabBelowRight && tabBelowRight->IsSelected())
  397.             {
  398.                 dc.DrawLine(
  399.                         tabRight,
  400.                         (long)raisedTop,
  401.                         tabRight,
  402.                         tabTop + 1
  403.                         );
  404.             }
  405.             else
  406.             {
  407.                 dc.DrawLine(
  408.                         tabRight,
  409.                         top - 1,
  410.                         tabRight,
  411.                         tabTop + 1
  412.                         );
  413.             }
  414.         }
  415.  
  416.         dc.SetPen(*wxBLACK_PEN);
  417.         dc.DrawPoint(
  418.                 tabRight,
  419.                 tabTop + 1
  420.                 );
  421.         dc.DrawPoint(
  422.                 tabRight + 1,
  423.                 tabTop + 2
  424.                 );
  425.         if (GetRowPosition() >= maxPositions - 1)
  426.         {
  427.             // draw right hand edge to bottom of view
  428.             dc.DrawLine(
  429.                     tabRight + 1,
  430.                     bottom + 1,
  431.                     tabRight + 1,
  432.                     tabTop + 2
  433.                     );
  434.             dc.DrawLine(
  435.                     tabRight + 1,
  436.                     bottom + 1,
  437.                     (tabRight - m_view->GetHorizontalTabOffset()),
  438.                     bottom + 1
  439.                     );
  440.         }
  441.         else
  442.         {
  443.             // draw right hand edge of TAB
  444.             if (tabBelowRight && tabBelowRight->IsSelected())
  445.             {
  446.                 dc.DrawLine(
  447.                         tabRight + 1,
  448.                         (long)(raisedTop - 1),
  449.                         tabRight + 1,
  450.                         tabTop + 2
  451.                         );
  452.             }
  453.             else
  454.             {
  455.                 dc.DrawLine(
  456.                         tabRight + 1,
  457.                         top - 1,
  458.                         tabRight + 1,
  459.                         tabTop + 2
  460.                         );
  461.             }
  462.         }
  463.     }
  464.  
  465.     // Draw centered text
  466.     dc.SetPen(*wxBLACK_PEN);
  467.     if (m_isSelected)
  468.     {
  469.         dc.SetFont(*(m_view->GetSelectedTabFont()));
  470.     }
  471.     else
  472.     {
  473.         dc.SetFont(*(GetFont()));
  474.     }
  475.  
  476.     wxColour col(m_view->GetTextColour());
  477.     dc.SetTextForeground(col);
  478.     dc.SetBackgroundMode(wxTRANSPARENT);
  479.     long textWidth, textHeight;
  480.     dc.GetTextExtent(GetLabel(), &textWidth, &textHeight);
  481.  
  482.     float textX = (tabLeft + tabRight - textWidth) / 2;
  483.     float textY = (tabInc + tabTop + m_view->GetVerticalTabTextSpacing());
  484.  
  485.     dc.DrawText(GetLabel(), (long)textX, (long)textY);
  486. #endif
  487. }
  488.  
  489. bool wxTabControl::HitTest(int x, int y) const
  490. {
  491.   // Top-left of tab control
  492.   int tabX1 = GetX() + m_view->GetViewRect().x;
  493.   int tabY1 = GetY() + m_view->GetViewRect().y;
  494.  
  495.   // Bottom-right
  496.   int tabX2 = tabX1 + GetWidth();
  497.   int tabY2 = tabY1 + GetHeight();
  498.  
  499.   if (x >= tabX1 && y >= tabY1 && x <= tabX2 && y <= tabY2)
  500.     return TRUE;
  501.   else
  502.     return FALSE;
  503. }
  504.  
  505. IMPLEMENT_DYNAMIC_CLASS(wxTabView, wxObject)
  506.  
  507. wxTabView::wxTabView(long style)
  508. {
  509.   m_noTabs = 0;
  510.   m_tabStyle = style;
  511.   m_tabSelection = -1;
  512.   m_tabHeight = 20;
  513.   m_tabSelectionHeight = m_tabHeight + 2;
  514.   m_tabWidth = 80;
  515.   m_tabHorizontalOffset = 10;
  516.   m_tabHorizontalSpacing = 2;
  517.   m_tabVerticalTextSpacing = 3;
  518.   m_topMargin = 5;
  519.   m_tabViewRect.x = 20;
  520.   m_tabViewRect.y = 20;
  521.   m_tabViewRect.width = 300;
  522.   m_tabViewRect.x = 300;
  523.   m_highlightColour = *wxWHITE;
  524.   m_shadowColour = wxColour(128, 128, 128);
  525.   m_backgroundColour = *wxLIGHT_GREY;
  526.   m_textColour = *wxBLACK;
  527.   m_highlightPen = wxWHITE_PEN;
  528.   m_shadowPen = wxGREY_PEN;
  529.   m_backgroundPen = wxLIGHT_GREY_PEN;
  530.   m_backgroundBrush = wxLIGHT_GREY_BRUSH;
  531.   m_tabFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
  532.   m_tabSelectedFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
  533.   m_window = (wxWindow *) NULL;
  534. }
  535.  
  536. wxTabView::~wxTabView()
  537. {
  538.   ClearTabs(TRUE);
  539. }
  540.  
  541. // Automatically positions tabs
  542. // TODO: this should just add the tab to a list, and then
  543. // a layout function (e.g. Realize) should be called when all tabs have been added.
  544. // The view rect could easily change as the view window is resized.
  545. wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *existingTab)
  546. {
  547.   // First, find which layer we should be adding to.
  548.   wxNode *node = m_layers.Last();
  549.   if (!node)
  550.   {
  551.     wxTabLayer *newLayer = new wxTabLayer;
  552.     node = m_layers.Append(newLayer);
  553.   }
  554.   // Check if adding another tab control would go off the
  555.   // right-hand edge of the layer.
  556.   wxTabLayer *tabLayer = (wxTabLayer *)node->Data();
  557.   wxNode *lastTabNode = tabLayer->Last();
  558.   if (lastTabNode)
  559.   {
  560.     wxTabControl *lastTab = (wxTabControl *)lastTabNode->Data();
  561.     // Start another layer (row).
  562.     // Tricky choice: can't just check if will be overlapping the edge, because
  563.     // this happens anyway for 2nd and subsequent rows.
  564.     // Should check this for 1st row, and then subsequent rows should not exceed 1st
  565.     // in length.
  566.     if (((tabLayer == m_layers.First()->Data()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing())
  567.               > GetViewRect().width)) ||
  568.         ((tabLayer != m_layers.First()->Data()) && (tabLayer->Number() == ((wxTabLayer *)m_layers.First()->Data())->Number())))
  569.     {
  570.       tabLayer = new wxTabLayer;
  571.       m_layers.Append(tabLayer);
  572.       lastTabNode = (wxNode *) NULL;
  573.     }
  574.   }
  575.   int layer = m_layers.Number() - 1;
  576.  
  577.   wxTabControl *tabControl = existingTab;
  578.   if (!existingTab)
  579.     tabControl = OnCreateTabControl();
  580.   tabControl->SetRowPosition(tabLayer->Number());
  581.   tabControl->SetColPosition(layer);
  582.  
  583.   wxTabControl *lastTab = (wxTabControl *) NULL;
  584.   if (lastTabNode)
  585.     lastTab = (wxTabControl *)lastTabNode->Data();
  586.  
  587.   // Top of new tab
  588.   int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight());
  589.   // Offset from view top-left
  590.   int horizontalOffset = 0;
  591.   if (!lastTab)
  592.     horizontalOffset = layer*GetHorizontalTabOffset();
  593.   else
  594.     horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing();
  595.  
  596.   tabControl->SetPosition(horizontalOffset, verticalOffset);
  597.   tabControl->SetSize(GetTabWidth(), GetTabHeight());
  598.   tabControl->SetId(id);
  599.   tabControl->SetLabel(label);
  600.   tabControl->SetFont(* GetTabFont());
  601.  
  602.   tabLayer->Append(tabControl);
  603.   m_noTabs ++;
  604.  
  605.   return tabControl;
  606. }
  607.  
  608. // Remove the tab without deleting the window
  609. bool wxTabView::RemoveTab(int id)
  610. {
  611.   wxNode *layerNode = m_layers.First();
  612.   while (layerNode)
  613.   {
  614.     wxTabLayer *layer = (wxTabLayer *)layerNode->Data();
  615.     wxNode *tabNode = layer->First();
  616.     while (tabNode)
  617.     {
  618.       wxTabControl *tab = (wxTabControl *)tabNode->Data();
  619.       if (tab->GetId() == id)
  620.       {
  621.         if (id == m_tabSelection)
  622.           m_tabSelection = -1;
  623.         delete tab;
  624.         delete tabNode;
  625.         m_noTabs --;
  626.  
  627.         // The layout has changed
  628.         LayoutTabs();
  629.         return TRUE;
  630.       }
  631.       tabNode = tabNode->Next();
  632.     }
  633.     layerNode = layerNode->Next();
  634.   }
  635.   return FALSE;
  636. }
  637.  
  638. bool wxTabView::SetTabText(int id, const wxString& label)
  639. {
  640.     wxTabControl* control = FindTabControlForId(id);
  641.     if (!control)
  642.       return FALSE;
  643.     control->SetLabel(label);
  644.     return TRUE;
  645. }
  646.  
  647. wxString wxTabView::GetTabText(int id) const
  648. {
  649.     wxTabControl* control = FindTabControlForId(id);
  650.     if (!control)
  651.       return wxEmptyString;
  652.     else
  653.       return control->GetLabel();
  654. }
  655.  
  656. // Returns the total height of the tabs component -- this may be several
  657. // times the height of a tab, if there are several tab layers (rows).
  658. int wxTabView::GetTotalTabHeight()
  659. {
  660.   int minY = 0;
  661.  
  662.   wxNode *layerNode = m_layers.First();
  663.   while (layerNode)
  664.   {
  665.     wxTabLayer *layer = (wxTabLayer *)layerNode->Data();
  666.     wxNode *tabNode = layer->First();
  667.     while (tabNode)
  668.     {
  669.       wxTabControl *tab = (wxTabControl *)tabNode->Data();
  670.  
  671.       if (tab->GetY() < minY)
  672.         minY = tab->GetY();
  673.  
  674.       tabNode = tabNode->Next();
  675.     }
  676.     layerNode = layerNode->Next();
  677.   }
  678.  
  679.   return - minY;
  680. }
  681.  
  682. void wxTabView::ClearTabs(bool deleteTabs)
  683. {
  684.   wxNode *layerNode = m_layers.First();
  685.   while (layerNode)
  686.   {
  687.     wxTabLayer *layer = (wxTabLayer *)layerNode->Data();
  688.     wxNode *tabNode = layer->First();
  689.     while (tabNode)
  690.     {
  691.       wxTabControl *tab = (wxTabControl *)tabNode->Data();
  692.       if (deleteTabs)
  693.         delete tab;
  694.       wxNode *next = tabNode->Next();
  695.       delete tabNode;
  696.       tabNode = next;
  697.     }
  698.     wxNode *nextLayerNode = layerNode->Next();
  699.     delete layer;
  700.     delete layerNode;
  701.     layerNode = nextLayerNode;
  702.   }
  703.   m_noTabs = 0;
  704.   m_tabSelection = -1;
  705. }
  706.  
  707.  
  708. // Layout tabs (optional, e.g. if resizing window)
  709. void wxTabView::LayoutTabs(void)
  710. {
  711.   // Make a list of the tab controls, deleting the wxTabLayers.
  712.   wxList controls;
  713.  
  714.   wxNode *layerNode = m_layers.First();
  715.   while (layerNode)
  716.   {
  717.     wxTabLayer *layer = (wxTabLayer *)layerNode->Data();
  718.     wxNode *tabNode = layer->First();
  719.     while (tabNode)
  720.     {
  721.       wxTabControl *tab = (wxTabControl *)tabNode->Data();
  722.       controls.Append(tab);
  723.       wxNode *next = tabNode->Next();
  724.       delete tabNode;
  725.       tabNode = next;
  726.     }
  727.     wxNode *nextLayerNode = layerNode->Next();
  728.     delete layer;
  729.     delete layerNode;
  730.     layerNode = nextLayerNode;
  731.   }
  732.  
  733.   wxTabControl *lastTab = (wxTabControl *) NULL;
  734.  
  735.   wxTabLayer *currentLayer = new wxTabLayer;
  736.   m_layers.Append(currentLayer);
  737.  
  738.   wxNode *node = controls.First();
  739.   while (node)
  740.   {
  741.     wxTabControl *tabControl = (wxTabControl *)node->Data();
  742.     if (lastTab)
  743.     {
  744.       // Start another layer (row).
  745.       // Tricky choice: can't just check if will be overlapping the edge, because
  746.       // this happens anyway for 2nd and subsequent rows.
  747.       // Should check this for 1st row, and then subsequent rows should not exceed 1st
  748.       // in length.
  749.       if (((currentLayer == m_layers.First()->Data()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing())
  750.                 > GetViewRect().width)) ||
  751.           ((currentLayer != m_layers.First()->Data()) && (currentLayer->Number() == ((wxTabLayer *)m_layers.First()->Data())->Number())))
  752.      {
  753.        currentLayer = new wxTabLayer;
  754.        m_layers.Append(currentLayer);
  755.        lastTab = (wxTabControl *) NULL;
  756.      }
  757.     }
  758.  
  759.     int layer = m_layers.Number() - 1;
  760.  
  761.     tabControl->SetRowPosition(currentLayer->Number());
  762.     tabControl->SetColPosition(layer);
  763.  
  764.     // Top of new tab
  765.     int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight());
  766.     // Offset from view top-left
  767.     int horizontalOffset = 0;
  768.     if (!lastTab)
  769.       horizontalOffset = layer*GetHorizontalTabOffset();
  770.     else
  771.       horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing();
  772.  
  773.     tabControl->SetPosition(horizontalOffset, verticalOffset);
  774.     tabControl->SetSize(GetTabWidth(), GetTabHeight());
  775.  
  776.     currentLayer->Append(tabControl);
  777.     lastTab = tabControl;
  778.  
  779.     node = node->Next();
  780.   }
  781.  
  782.   // Move the selected tab to the bottom
  783.   wxTabControl *control = FindTabControlForId(m_tabSelection);
  784.   if (control)
  785.     MoveSelectionTab(control);
  786.  
  787. }
  788.  
  789. // Draw all tabs
  790. void wxTabView::Draw(wxDC& dc)
  791. {
  792.         // Don't draw anything if there are no tabs.
  793.         if (GetNumberOfTabs() == 0)
  794.           return;
  795.  
  796.     // Draw top margin area (beneath tabs and above view area)
  797.     if (GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR)
  798.     {
  799.         dc.SetPen(*wxTRANSPARENT_PEN);
  800.         dc.SetBrush(*GetBackgroundBrush());
  801.  
  802.         // Add 1 because the pen is transparent. Under Motif, may be different.
  803.         dc.DrawRectangle(
  804.                 m_tabViewRect.x,
  805.                 (m_tabViewRect.y - m_topMargin),
  806.                 (m_tabViewRect.width + 1),
  807.                 (m_topMargin + 1)
  808.                 );
  809.     }
  810.  
  811.     // Draw layers in reverse order
  812.     wxNode *node = m_layers.Last();
  813.     while (node)
  814.     {
  815.         wxTabLayer *layer = (wxTabLayer *)node->Data();
  816.         wxNode *node2 = layer->First();
  817.         while (node2)
  818.         {
  819.             wxTabControl *control = (wxTabControl *)node2->Data();
  820.             control->OnDraw(dc, (node2->Next() == NULL));
  821.             node2 = node2->Next();
  822.         }
  823.  
  824.         node = node->Previous();
  825.     }
  826.  
  827.  
  828. #ifndef wxUSE_NEW_METHOD
  829.     if (GetTabStyle() & wxTAB_STYLE_DRAW_BOX)
  830.     {
  831.         dc.SetPen(* GetShadowPen());
  832.  
  833.         // Draw bottom line
  834.         dc.DrawLine(
  835.                 (GetViewRect().x + 1),
  836.                 (GetViewRect().y + GetViewRect().height),
  837.                 (GetViewRect().x + GetViewRect().width + 1),
  838.                 (GetViewRect().y + GetViewRect().height)
  839.                 );
  840.  
  841.         // Draw right line
  842.         dc.DrawLine(
  843.                 (GetViewRect().x + GetViewRect().width),
  844.                 (GetViewRect().y - GetTopMargin() + 1),
  845.                 (GetViewRect().x + GetViewRect().width),
  846.                 (GetViewRect().y + GetViewRect().height)
  847.                 );
  848.  
  849.         dc.SetPen(* wxBLACK_PEN);
  850.  
  851.         // Draw bottom line
  852.         dc.DrawLine(
  853.                 (GetViewRect().x),
  854.                 (GetViewRect().y + GetViewRect().height + 1),
  855. #if defined(__WXMOTIF__)
  856.                 (GetViewRect().x + GetViewRect().width + 1),
  857. #else
  858.                 (GetViewRect().x + GetViewRect().width + 2),
  859. #endif
  860.  
  861.                 (GetViewRect().y + GetViewRect().height + 1)
  862.                 );
  863.  
  864.         // Draw right line
  865.         dc.DrawLine(
  866.                 (GetViewRect().x + GetViewRect().width + 1),
  867.                 (GetViewRect().y - GetTopMargin()),
  868.                 (GetViewRect().x + GetViewRect().width + 1),
  869.                 (GetViewRect().y + GetViewRect().height + 1)
  870.                 );
  871.     }
  872. #endif
  873. }
  874.  
  875. // Process mouse event, return FALSE if we didn't process it
  876. bool wxTabView::OnEvent(wxMouseEvent& event)
  877. {
  878.   if (!event.LeftDown())
  879.     return FALSE;
  880.  
  881.   wxCoord x, y;
  882.   event.GetPosition(&x, &y);
  883.  
  884.   wxTabControl *hitControl = (wxTabControl *) NULL;
  885.  
  886.   wxNode *node = m_layers.First();
  887.   while (node)
  888.   {
  889.     wxTabLayer *layer = (wxTabLayer *)node->Data();
  890.     wxNode *node2 = layer->First();
  891.     while (node2)
  892.     {
  893.       wxTabControl *control = (wxTabControl *)node2->Data();
  894.       if (control->HitTest((int)x, (int)y))
  895.       {
  896.         hitControl = control;
  897.         node = (wxNode *) NULL;
  898.         node2 = (wxNode *) NULL;
  899.       }
  900.       else
  901.         node2 = node2->Next();
  902.     }
  903.  
  904.     if (node)
  905.       node = node->Next();
  906.   }
  907.  
  908.   if (!hitControl)
  909.     return FALSE;
  910.  
  911.   wxTabControl *currentTab = FindTabControlForId(m_tabSelection);
  912.  
  913.   if (hitControl == currentTab)
  914.     return FALSE;
  915.  
  916.   ChangeTab(hitControl);
  917.  
  918.   return TRUE;
  919. }
  920.  
  921. bool wxTabView::ChangeTab(wxTabControl *control)
  922. {
  923.   wxTabControl *currentTab = FindTabControlForId(m_tabSelection);
  924.   int oldTab = -1;
  925.   if (currentTab)
  926.     oldTab = currentTab->GetId();
  927.  
  928.   if (control == currentTab)
  929.     return TRUE;
  930.  
  931.   if (m_layers.Number() == 0)
  932.     return FALSE;
  933.  
  934.   if (!OnTabPreActivate(control->GetId(), oldTab))
  935.     return FALSE;
  936.  
  937.   // Move the tab to the bottom
  938.   MoveSelectionTab(control);
  939.  
  940.   if (currentTab)
  941.     currentTab->SetSelected(FALSE);
  942.  
  943.   control->SetSelected(TRUE);
  944.   m_tabSelection = control->GetId();
  945.  
  946.   OnTabActivate(control->GetId(), oldTab);
  947.  
  948.   // Leave window refresh for the implementing window
  949.  
  950.   return TRUE;
  951. }
  952.  
  953. // Move the selected tab to the bottom layer, if necessary,
  954. // without calling app activation code
  955. bool wxTabView::MoveSelectionTab(wxTabControl *control)
  956. {
  957.   if (m_layers.Number() == 0)
  958.     return FALSE;
  959.  
  960.   wxTabLayer *firstLayer = (wxTabLayer *)m_layers.First()->Data();
  961.  
  962.   // Find what column this tab is at, so we can swap with the one at the bottom.
  963.   // If we're on the bottom layer, then no need to swap.
  964.   if (!firstLayer->Member(control))
  965.   {
  966.     // Do a swap
  967.     int col = 0;
  968.     wxNode *thisNode = FindTabNodeAndColumn(control, &col);
  969.     if (!thisNode)
  970.       return FALSE;
  971.     wxNode *otherNode = firstLayer->Nth(col);
  972.     if (!otherNode)
  973.       return FALSE;
  974.  
  975.     // If this is already in the bottom layer, return now
  976.     if (otherNode == thisNode)
  977.       return TRUE;
  978.  
  979.     wxTabControl *otherTab = (wxTabControl *)otherNode->Data();
  980.  
  981.     // We now have pointers to the tab to be changed to,
  982.     // and the tab on the first layer. Swap tab structures and
  983.     // position details.
  984.  
  985.     int thisX = control->GetX();
  986.     int thisY = control->GetY();
  987.     int thisColPos = control->GetColPosition();
  988.     int otherX = otherTab->GetX();
  989.     int otherY = otherTab->GetY();
  990.     int otherColPos = otherTab->GetColPosition();
  991.  
  992.     control->SetPosition(otherX, otherY);
  993.     control->SetColPosition(otherColPos);
  994.     otherTab->SetPosition(thisX, thisY);
  995.     otherTab->SetColPosition(thisColPos);
  996.  
  997.     // Swap the data for the nodes
  998.     thisNode->SetData(otherTab);
  999.     otherNode->SetData(control);
  1000.   }
  1001.   return TRUE;
  1002. }
  1003.  
  1004. // Called when a tab is activated
  1005. void wxTabView::OnTabActivate(int /*activateId*/, int /*deactivateId*/)
  1006. {
  1007. }
  1008.  
  1009. void wxTabView::SetHighlightColour(const wxColour& col)
  1010. {
  1011.   m_highlightColour = col;
  1012.   m_highlightPen = wxThePenList->FindOrCreatePen(col, 1, wxSOLID);
  1013. }
  1014.  
  1015. void wxTabView::SetShadowColour(const wxColour& col)
  1016. {
  1017.   m_shadowColour = col;
  1018.   m_shadowPen = wxThePenList->FindOrCreatePen(col, 1, wxSOLID);
  1019. }
  1020.  
  1021. void wxTabView::SetBackgroundColour(const wxColour& col)
  1022. {
  1023.   m_backgroundColour = col;
  1024.   m_backgroundPen = wxThePenList->FindOrCreatePen(col, 1, wxSOLID);
  1025.   m_backgroundBrush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID);
  1026. }
  1027.  
  1028. void wxTabView::SetTabSelection(int sel, bool activateTool)
  1029. {
  1030.   if ( sel==m_tabSelection )
  1031.     return;
  1032.  
  1033.   int oldSel = m_tabSelection;
  1034.   wxTabControl *control = FindTabControlForId(sel);
  1035.   wxTabControl *oldControl = FindTabControlForId(m_tabSelection);
  1036.  
  1037.   if (!OnTabPreActivate(sel, oldSel))
  1038.     return;
  1039.  
  1040.   if (control)
  1041.     control->SetSelected((sel != -1)); // TODO ??
  1042.   else if (sel != -1)
  1043.   {
  1044.     wxFAIL_MSG(_("Could not find tab for id"));
  1045.     return;
  1046.   }
  1047.  
  1048.   if (oldControl)
  1049.     oldControl->SetSelected(FALSE);
  1050.  
  1051.   m_tabSelection = sel;
  1052.  
  1053.   if (control)
  1054.     MoveSelectionTab(control);
  1055.  
  1056.   if (activateTool)
  1057.     OnTabActivate(sel, oldSel);
  1058. }
  1059.  
  1060. // Find tab control for id
  1061. wxTabControl *wxTabView::FindTabControlForId(int id) const
  1062. {
  1063.   wxNode *node1 = m_layers.First();
  1064.   while (node1)
  1065.   {
  1066.     wxTabLayer *layer = (wxTabLayer *)node1->Data();
  1067.     wxNode *node2 = layer->First();
  1068.     while (node2)
  1069.     {
  1070.       wxTabControl *control = (wxTabControl *)node2->Data();
  1071.       if (control->GetId() == id)
  1072.         return control;
  1073.       node2 = node2->Next();
  1074.     }
  1075.     node1 = node1->Next();
  1076.   }
  1077.   return (wxTabControl *) NULL;
  1078. }
  1079.  
  1080. // Find tab control for layer, position (starting from zero)
  1081. wxTabControl *wxTabView::FindTabControlForPosition(int layer, int position) const
  1082. {
  1083.   wxNode *node1 = m_layers.Nth(layer);
  1084.   if (!node1)
  1085.     return (wxTabControl *) NULL;
  1086.   wxTabLayer *tabLayer = (wxTabLayer *)node1->Data();
  1087.   wxNode *node2 = tabLayer->Nth(position);
  1088.   if (!node2)
  1089.     return (wxTabControl *) NULL;
  1090.   return (wxTabControl *)node2->Data();
  1091. }
  1092.  
  1093. // Find the node and the column at which this control is positioned.
  1094. wxNode *wxTabView::FindTabNodeAndColumn(wxTabControl *control, int *col) const
  1095. {
  1096.   wxNode *node1 = m_layers.First();
  1097.   while (node1)
  1098.   {
  1099.     wxTabLayer *layer = (wxTabLayer *)node1->Data();
  1100.     int c = 0;
  1101.     wxNode *node2 = layer->First();
  1102.     while (node2)
  1103.     {
  1104.       wxTabControl *cnt = (wxTabControl *)node2->Data();
  1105.       if (cnt == control)
  1106.       {
  1107.         *col = c;
  1108.         return node2;
  1109.       }
  1110.       node2 = node2->Next();
  1111.       c ++;
  1112.     }
  1113.     node1 = node1->Next();
  1114.   }
  1115.   return (wxNode *) NULL;
  1116. }
  1117.  
  1118. int wxTabView::CalculateTabWidth(int noTabs, bool adjustView)
  1119. {
  1120.   m_tabWidth = (int)((m_tabViewRect.width - ((noTabs - 1)*GetHorizontalTabSpacing()))/noTabs);
  1121.   if (adjustView)
  1122.   {
  1123.     m_tabViewRect.width = noTabs*m_tabWidth + ((noTabs-1)*GetHorizontalTabSpacing());
  1124.   }
  1125.   return m_tabWidth;
  1126. }
  1127.  
  1128. /*
  1129.  * wxTabbedDialog
  1130.  */
  1131.  
  1132. IMPLEMENT_CLASS(wxTabbedDialog, wxDialog)
  1133.  
  1134. BEGIN_EVENT_TABLE(wxTabbedDialog, wxDialog)
  1135.     EVT_CLOSE(wxTabbedDialog::OnCloseWindow)
  1136.     EVT_MOUSE_EVENTS(wxTabbedDialog::OnMouseEvent)
  1137.     EVT_PAINT(wxTabbedDialog::OnPaint)
  1138. END_EVENT_TABLE()
  1139.  
  1140. wxTabbedDialog::wxTabbedDialog(wxWindow *parent, wxWindowID id,
  1141.     const wxString& title,
  1142.     const wxPoint& pos, const wxSize& size,
  1143.     long windowStyle, const wxString& name):
  1144.    wxDialog(parent, id, title, pos, size, windowStyle, name)
  1145. {
  1146.   m_tabView = (wxTabView *) NULL;
  1147. }
  1148.  
  1149. wxTabbedDialog::~wxTabbedDialog(void)
  1150. {
  1151.   if (m_tabView)
  1152.     delete m_tabView;
  1153. }
  1154.  
  1155. void wxTabbedDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event) )
  1156. {
  1157.   Destroy();
  1158. }
  1159.  
  1160. void wxTabbedDialog::OnMouseEvent(wxMouseEvent& event )
  1161. {
  1162.   if (m_tabView)
  1163.     m_tabView->OnEvent(event);
  1164. }
  1165.  
  1166. void wxTabbedDialog::OnPaint(wxPaintEvent& WXUNUSED(event) )
  1167. {
  1168.     wxPaintDC dc(this);
  1169.     if (m_tabView)
  1170.         m_tabView->Draw(dc);
  1171. }
  1172.  
  1173. /*
  1174.  * wxTabbedPanel
  1175.  */
  1176.  
  1177. IMPLEMENT_CLASS(wxTabbedPanel, wxPanel)
  1178.  
  1179. BEGIN_EVENT_TABLE(wxTabbedPanel, wxPanel)
  1180.     EVT_MOUSE_EVENTS(wxTabbedPanel::OnMouseEvent)
  1181.     EVT_PAINT(wxTabbedPanel::OnPaint)
  1182. END_EVENT_TABLE()
  1183.  
  1184. wxTabbedPanel::wxTabbedPanel(wxWindow *parent, wxWindowID id, const wxPoint& pos,
  1185.    const wxSize& size, long windowStyle, const wxString& name):
  1186.    wxPanel(parent, id, pos, size, windowStyle, name)
  1187. {
  1188.   m_tabView = (wxTabView *) NULL;
  1189. }
  1190.  
  1191. wxTabbedPanel::~wxTabbedPanel(void)
  1192. {
  1193.   delete m_tabView;
  1194. }
  1195.  
  1196. void wxTabbedPanel::OnMouseEvent(wxMouseEvent& event)
  1197. {
  1198.   if (m_tabView)
  1199.     m_tabView->OnEvent(event);
  1200. }
  1201.  
  1202. void wxTabbedPanel::OnPaint(wxPaintEvent& WXUNUSED(event) )
  1203. {
  1204.     wxPaintDC dc(this);
  1205.     if (m_tabView)
  1206.         m_tabView->Draw(dc);
  1207. }
  1208.  
  1209. /*
  1210.  * wxPanelTabView
  1211.  */
  1212.  
  1213. IMPLEMENT_CLASS(wxPanelTabView, wxTabView)
  1214.  
  1215. wxPanelTabView::wxPanelTabView(wxPanel *pan, long style): wxTabView(style), m_tabWindows(wxKEY_INTEGER)
  1216. {
  1217.   m_panel = pan;
  1218.   m_currentWindow = (wxWindow *) NULL;
  1219.  
  1220.   if (m_panel->IsKindOf(CLASSINFO(wxTabbedDialog)))
  1221.     ((wxTabbedDialog *)m_panel)->SetTabView(this);
  1222.   else if (m_panel->IsKindOf(CLASSINFO(wxTabbedPanel)))
  1223.     ((wxTabbedPanel *)m_panel)->SetTabView(this);
  1224.  
  1225.   SetWindow(m_panel);
  1226. }
  1227.  
  1228. wxPanelTabView::~wxPanelTabView(void)
  1229. {
  1230.   ClearWindows(TRUE);
  1231. }
  1232.  
  1233. // Called when a tab is activated
  1234. void wxPanelTabView::OnTabActivate(int activateId, int deactivateId)
  1235. {
  1236.   if (!m_panel)
  1237.     return;
  1238.  
  1239.   wxWindow *oldWindow = ((deactivateId == -1) ? 0 : GetTabWindow(deactivateId));
  1240.   wxWindow *newWindow = GetTabWindow(activateId);
  1241.  
  1242.   if (oldWindow)
  1243.     oldWindow->Show(FALSE);
  1244.   if (newWindow)
  1245.     newWindow->Show(TRUE);
  1246.  
  1247.   m_panel->Refresh();
  1248. }
  1249.  
  1250.  
  1251. void wxPanelTabView::AddTabWindow(int id, wxWindow *window)
  1252. {
  1253.   m_tabWindows.Append((long)id, window);
  1254.   window->Show(FALSE);
  1255. }
  1256.  
  1257. wxWindow *wxPanelTabView::GetTabWindow(int id) const
  1258. {
  1259.   wxNode *node = m_tabWindows.Find((long)id);
  1260.   if (!node)
  1261.     return (wxWindow *) NULL;
  1262.   return (wxWindow *)node->Data();
  1263. }
  1264.  
  1265. void wxPanelTabView::ClearWindows(bool deleteWindows)
  1266. {
  1267.   if (deleteWindows)
  1268.     m_tabWindows.DeleteContents(TRUE);
  1269.   m_tabWindows.Clear();
  1270.   m_tabWindows.DeleteContents(FALSE);
  1271. }
  1272.  
  1273. void wxPanelTabView::ShowWindowForTab(int id)
  1274. {
  1275.   wxWindow *newWindow = GetTabWindow(id);
  1276.   if (newWindow == m_currentWindow)
  1277.     return;
  1278.   if (m_currentWindow)
  1279.     m_currentWindow->Show(FALSE);
  1280.   newWindow->Show(TRUE);
  1281.   newWindow->Refresh();
  1282. }
  1283.  
  1284. #endif // wxUSE_TAB_DIALOG
  1285.