1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Generic tabbed dialogs
4 // Author: Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "tabg.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
34 IMPLEMENT_DYNAMIC_CLASS(wxTabControl
, wxObject
)
36 IMPLEMENT_DYNAMIC_CLASS(wxTabLayer
, wxList
)
38 wxTabControl::wxTabControl(wxTabView
*v
)
42 m_labelFont
= (wxFont
*) NULL
;
52 wxTabControl::~wxTabControl(void)
56 void wxTabControl::OnDraw(wxDC
& dc
, bool lastInRow
)
58 // Old, but in some ways better (drawing opaque tabs)
63 // Top-left of tab view area
64 int viewX
= m_view
->GetViewRect().x
;
65 int viewY
= m_view
->GetViewRect().y
;
67 // Top-left of tab control
68 int tabX
= GetX() + viewX
;
69 int tabY
= GetY() + viewY
;
73 tabHeightInc
= (view
->GetTabSelectionHeight() - view
->GetTabHeight());
77 dc
.SetPen(wxTRANSPARENT_PEN
);
79 // Draw grey background
80 if (view
->GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR
)
82 dc
.SetBrush(m_view
->GetBackgroundBrush());
84 // Add 1 because the pen is transparent. Under Motif, may be different.
85 dc
.DrawRectangle(tabX
, tabY
, (GetWidth()+1), (GetHeight() + 1 + tabHeightInc
));
88 // Draw highlight and shadow
89 dc
.SetPen(m_view
->GetHighlightPen());
91 // Calculate the top of the tab beneath. It's the height of the tab, MINUS
92 // a bit if the tab below happens to be selected. Check.
93 wxTabControl
*tabBeneath
= NULL
;
95 if (GetColPosition() > 0)
96 tabBeneath
= m_view
->FindTabControlForPosition(GetColPosition() - 1, GetRowPosition());
97 if (tabBeneath
&& tabBeneath
->IsSelected())
98 subtractThis
= (m_view
->GetTabSelectionHeight() - m_view
->GetTabHeight());
100 // Vertical highlight: if first tab, draw to bottom of view
101 if (tabX
== m_view
->GetViewRect().x
&& (m_view
->GetTabStyle() & wxTAB_STYLE_DRAW_BOX
))
102 dc
.DrawLine(tabX
, tabY
, tabX
, (m_view
->GetViewRect().y
+ m_view
->GetViewRect().height
));
103 else if (tabX
== m_view
->GetViewRect().x
)
104 // Not box drawing, just to top of view.
105 dc
.DrawLine(tabX
, tabY
, tabX
, (m_view
->GetViewRect().y
));
107 dc
.DrawLine(tabX
, tabY
, tabX
, (tabY
+ GetHeight() + tabHeightInc
- subtractThis
));
109 dc
.DrawLine(tabX
, tabY
, (tabX
+ GetWidth()), tabY
);
110 dc
.SetPen(m_view
->GetShadowPen());
112 // Test if we're outside the right-hand edge of the view area
113 if (((tabX
+ GetWidth()) >= m_view
->GetViewRect().x
+ m_view
->GetViewRect().width
) && (m_view
->GetTabStyle() & wxTAB_STYLE_DRAW_BOX
))
115 int bottomY
= m_view
->GetViewRect().y
+ m_view
->GetViewRect().height
+ GetY() + m_view
->GetTabHeight() + m_view
->GetTopMargin();
116 // Add a tab height since we wish to draw to the bottom of the view.
117 dc
.DrawLine((tabX
+ GetWidth()), tabY
,
118 (tabX
+ GetWidth()), bottomY
);
120 // Calculate the far-right of the view, since we don't wish to
122 int rightOfView
= m_view
->GetViewRect().x
+ m_view
->GetViewRect().width
+ 1;
124 // Draw the horizontal bit to connect to the view rectangle
125 dc
.DrawLine((wxMax((tabX
+ GetWidth() - m_view
->GetHorizontalTabOffset()), rightOfView
)), (bottomY
-1),
126 (tabX
+ GetWidth()), (bottomY
-1));
128 // Draw black line to emphasize shadow
129 dc
.SetPen(wxBLACK_PEN
);
130 dc
.DrawLine((tabX
+ GetWidth() + 1), (tabY
+1),
131 (tabX
+ GetWidth() + 1), bottomY
);
133 // Draw the horizontal bit to connect to the view rectangle
134 dc
.DrawLine((wxMax((tabX
+ GetWidth() - m_view
->GetHorizontalTabOffset()), rightOfView
)), (bottomY
),
135 (tabX
+ GetWidth() + 1), (bottomY
));
141 // 25/5/97 UNLESS it's less than the max number of positions in this row
143 int topY
= m_view
->GetViewRect().y
- m_view
->GetTopMargin();
145 int maxPositions
= ((wxTabLayer
*)m_view
->GetLayers().Nth(0)->Data())->Number();
147 // Only down to the bottom of the tab, not to the top of the view
148 if ( GetColPosition() < maxPositions
)
149 topY
= tabY
+ GetHeight() + tabHeightInc
;
152 dc
.DrawLine((tabX
+ GetWidth()), tabY
, (tabX
+ GetWidth()), topY
);
153 // Draw black line to emphasize shadow
154 dc
.SetPen(wxBLACK_PEN
);
155 dc
.DrawLine((tabX
+ GetWidth() + 1), (tabY
+1), (tabX
+ GetWidth() + 1),
160 // Calculate the top of the tab beneath. It's the height of the tab, MINUS
161 // a bit if the tab below (and next col along) happens to be selected. Check.
162 wxTabControl
*tabBeneath
= NULL
;
163 int subtractThis
= 0;
164 if (GetColPosition() > 0)
165 tabBeneath
= m_view
->FindTabControlForPosition(GetColPosition() - 1, GetRowPosition() + 1);
166 if (tabBeneath
&& tabBeneath
->IsSelected())
167 subtractThis
= (m_view
->GetTabSelectionHeight() - m_view
->GetTabHeight());
169 // Draw only to next tab down.
170 dc
.DrawLine((tabX
+ GetWidth()), tabY
,
171 (tabX
+ GetWidth()), (tabY
+ GetHeight() + tabHeightInc
- subtractThis
));
173 // Draw black line to emphasize shadow
174 dc
.SetPen(wxBLACK_PEN
);
175 dc
.DrawLine((tabX
+ GetWidth() + 1), (tabY
+1), (tabX
+ GetWidth() + 1),
176 (tabY
+ GetHeight() + tabHeightInc
- subtractThis
));
180 // Draw centered text
181 int textY
= tabY
+ m_view
->GetVerticalTabTextSpacing() + tabHeightInc
;
184 dc
.SetFont(m_view
->GetSelectedTabFont());
186 dc
.SetFont(GetFont());
188 wxColour
col(m_view
->GetTextColour());
189 dc
.SetTextForeground(&col
);
190 // dc.SetTextForeground(&(m_view->GetTextColour()));
191 dc
.SetBackgroundMode(wxTRANSPARENT
);
192 float textWidth
, textHeight
;
193 dc
.GetTextExtent(GetLabel(), &textWidth
, &textHeight
);
195 int textX
= (int)(tabX
+ (GetWidth() - textWidth
)/2.0);
196 dc
.DrawText(GetLabel(), textX
, textY
);
200 dc
.SetPen(m_view
->GetHighlightPen());
202 // Draw white highlight from the tab's left side to the left hand edge of the view
203 dc
.DrawLine(m_view
->GetViewRect().x
, (tabY
+ GetHeight() + tabHeightInc
),
204 tabX
, (tabY
+ GetHeight() + tabHeightInc
));
206 // Draw white highlight from the tab's right side to the right hand edge of the view
207 dc
.DrawLine((tabX
+ GetWidth()), (tabY
+ GetHeight() + tabHeightInc
),
208 m_view
->GetViewRect().x
+ m_view
->GetViewRect().width
, (tabY
+ GetHeight() + tabHeightInc
));
212 // New HEL version with rounder tabs
219 tabInc
= m_view
->GetTabSelectionHeight() - m_view
->GetTabHeight();
221 int tabLeft
= GetX() + m_view
->GetViewRect().x
;
222 int tabTop
= GetY() + m_view
->GetViewRect().y
- tabInc
;
223 int tabRight
= tabLeft
+ m_view
->GetTabWidth();
224 int left
= m_view
->GetViewRect().x
;
225 int top
= tabTop
+ m_view
->GetTabHeight() + tabInc
;
226 int right
= left
+ m_view
->GetViewRect().width
;
227 int bottom
= top
+ m_view
->GetViewRect().height
;
231 // TAB is selected - draw TAB and the View's full outline
233 dc
.SetPen(*(m_view
->GetHighlightPen()));
236 pnts
[n
].x
= left
; pnts
[n
++].y
= bottom
;
237 pnts
[n
].x
= left
; pnts
[n
++].y
= top
;
238 pnts
[n
].x
= tabLeft
; pnts
[n
++].y
= top
;
239 pnts
[n
].x
= tabLeft
; pnts
[n
++].y
= tabTop
+ 2;
240 pnts
[n
].x
= tabLeft
+ 2; pnts
[n
++].y
= tabTop
;
241 pnts
[n
].x
= tabRight
- 1; pnts
[n
++].y
= tabTop
;
242 dc
.DrawLines(n
, pnts
);
253 dc
.SetPen(*(m_view
->GetShadowPen()));
273 dc
.SetPen(*wxBLACK_PEN
);
315 // TAB is not selected - just draw TAB outline and RH edge
316 // if the TAB is the last in the row
318 int maxPositions
= ((wxTabLayer
*)m_view
->GetLayers().Nth(0)->Data())->Number();
319 wxTabControl
* tabBelow
= 0;
320 wxTabControl
* tabBelowRight
= 0;
321 if (GetColPosition() > 0)
323 tabBelow
= m_view
->FindTabControlForPosition(
324 GetColPosition() - 1,
328 if (!lastInRow
&& GetColPosition() > 0)
330 tabBelowRight
= m_view
->FindTabControlForPosition(
331 GetColPosition() - 1,
336 float raisedTop
= top
- m_view
->GetTabSelectionHeight() +
337 m_view
->GetTabHeight();
339 dc
.SetPen(*(m_view
->GetHighlightPen()));
345 if (tabBelow
&& tabBelow
->IsSelected())
347 pnts
[n
++].y
= (long)raisedTop
;
353 pnts
[n
].x
= tabLeft
; pnts
[n
++].y
= tabTop
+ 2;
354 pnts
[n
].x
= tabLeft
+ 2; pnts
[n
++].y
= tabTop
;
355 pnts
[n
].x
= tabRight
- 1; pnts
[n
++].y
= tabTop
;
356 dc
.DrawLines(n
, pnts
);
358 dc
.SetPen(*(m_view
->GetShadowPen()));
359 if (GetRowPosition() >= maxPositions
- 1)
370 (tabRight
- m_view
->GetHorizontalTabOffset()),
376 if (tabBelowRight
&& tabBelowRight
->IsSelected())
396 dc
.SetPen(*wxBLACK_PEN
);
405 if (GetRowPosition() >= maxPositions
- 1)
407 // draw right hand edge to bottom of view
417 (tabRight
- m_view
->GetHorizontalTabOffset()),
423 // draw right hand edge of TAB
424 if (tabBelowRight
&& tabBelowRight
->IsSelected())
428 (long)(raisedTop
- 1),
445 // Draw centered text
446 dc
.SetPen(*wxBLACK_PEN
);
449 dc
.SetFont(*(m_view
->GetSelectedTabFont()));
453 dc
.SetFont(*(GetFont()));
456 wxColour
col(m_view
->GetTextColour());
457 dc
.SetTextForeground(col
);
458 dc
.SetBackgroundMode(wxTRANSPARENT
);
459 long textWidth
, textHeight
;
460 dc
.GetTextExtent(GetLabel(), &textWidth
, &textHeight
);
462 float textX
= (tabLeft
+ tabRight
- textWidth
) / 2;
463 float textY
= (tabInc
+ tabTop
+ m_view
->GetVerticalTabTextSpacing());
465 dc
.DrawText(GetLabel(), (long)textX
, (long)textY
);
469 bool wxTabControl::HitTest(int x
, int y
) const
471 // Top-left of tab control
472 int tabX1
= GetX() + m_view
->GetViewRect().x
;
473 int tabY1
= GetY() + m_view
->GetViewRect().y
;
476 int tabX2
= tabX1
+ GetWidth();
477 int tabY2
= tabY1
+ GetHeight();
479 if (x
>= tabX1
&& y
>= tabY1
&& x
<= tabX2
&& y
<= tabY2
)
485 IMPLEMENT_DYNAMIC_CLASS(wxTabView
, wxObject
)
487 wxTabView::wxTabView(long style
)
493 m_tabSelectionHeight
= m_tabHeight
+ 2;
495 m_tabHorizontalOffset
= 10;
496 m_tabHorizontalSpacing
= 2;
497 m_tabVerticalTextSpacing
= 3;
499 m_tabViewRect
.x
= 20;
500 m_tabViewRect
.y
= 20;
501 m_tabViewRect
.width
= 300;
502 m_tabViewRect
.x
= 300;
503 m_highlightColour
= *wxWHITE
;
504 m_shadowColour
= wxColour(128, 128, 128);
505 m_backgroundColour
= *wxLIGHT_GREY
;
506 m_textColour
= *wxBLACK
;
507 m_highlightPen
= wxWHITE_PEN
;
508 m_shadowPen
= wxGREY_PEN
;
509 m_backgroundPen
= wxLIGHT_GREY_PEN
;
510 m_backgroundBrush
= wxLIGHT_GREY_BRUSH
;
511 m_tabFont
= wxTheFontList
->FindOrCreateFont(9, wxSWISS
, wxNORMAL
, wxNORMAL
);
512 m_tabSelectedFont
= wxTheFontList
->FindOrCreateFont(9, wxSWISS
, wxNORMAL
, wxBOLD
);
513 m_window
= (wxWindow
*) NULL
;
516 wxTabView::~wxTabView()
520 // Automatically positions tabs
521 wxTabControl
*wxTabView::AddTab(int id
, const wxString
& label
, wxTabControl
*existingTab
)
523 // First, find which layer we should be adding to.
524 wxNode
*node
= m_layers
.Last();
527 wxTabLayer
*newLayer
= new wxTabLayer
;
528 node
= m_layers
.Append(newLayer
);
530 // Check if adding another tab control would go off the
531 // right-hand edge of the layer.
532 wxTabLayer
*tabLayer
= (wxTabLayer
*)node
->Data();
533 wxNode
*lastTabNode
= tabLayer
->Last();
536 wxTabControl
*lastTab
= (wxTabControl
*)lastTabNode
->Data();
537 // Start another layer (row).
538 // Tricky choice: can't just check if will be overlapping the edge, because
539 // this happens anyway for 2nd and subsequent rows.
540 // Should check this for 1st row, and then subsequent rows should not exceed 1st
542 if (((tabLayer
== m_layers
.First()->Data()) && ((lastTab
->GetX() + 2*lastTab
->GetWidth() + GetHorizontalTabSpacing())
543 > GetViewRect().width
)) ||
544 ((tabLayer
!= m_layers
.First()->Data()) && (tabLayer
->Number() == ((wxTabLayer
*)m_layers
.First()->Data())->Number())))
546 tabLayer
= new wxTabLayer
;
547 m_layers
.Append(tabLayer
);
548 lastTabNode
= (wxNode
*) NULL
;
551 int layer
= m_layers
.Number() - 1;
553 wxTabControl
*tabControl
= existingTab
;
555 tabControl
= OnCreateTabControl();
556 tabControl
->SetRowPosition(tabLayer
->Number());
557 tabControl
->SetColPosition(layer
);
559 wxTabControl
*lastTab
= (wxTabControl
*) NULL
;
561 lastTab
= (wxTabControl
*)lastTabNode
->Data();
564 int verticalOffset
= (- GetTopMargin()) - ((layer
+1)*GetTabHeight());
565 // Offset from view top-left
566 int horizontalOffset
= 0;
568 horizontalOffset
= layer
*GetHorizontalTabOffset();
570 horizontalOffset
= lastTab
->GetX() + GetTabWidth() + GetHorizontalTabSpacing();
572 tabControl
->SetPosition(horizontalOffset
, verticalOffset
);
573 tabControl
->SetSize(GetTabWidth(), GetTabHeight());
574 tabControl
->SetId(id
);
575 tabControl
->SetLabel(label
);
576 tabControl
->SetFont(GetTabFont());
578 tabLayer
->Append(tabControl
);
584 void wxTabView::ClearTabs(bool deleteTabs
)
586 wxNode
*layerNode
= m_layers
.First();
589 wxTabLayer
*layer
= (wxTabLayer
*)layerNode
->Data();
590 wxNode
*tabNode
= layer
->First();
593 wxTabControl
*tab
= (wxTabControl
*)tabNode
->Data();
596 wxNode
*next
= tabNode
->Next();
600 wxNode
*nextLayerNode
= layerNode
->Next();
603 layerNode
= nextLayerNode
;
607 // Layout tabs (optional, e.g. if resizing window)
608 void wxTabView::Layout(void)
610 // Make a list of the tab controls, deleting the wxTabLayers.
613 wxNode
*layerNode
= m_layers
.First();
616 wxTabLayer
*layer
= (wxTabLayer
*)layerNode
->Data();
617 wxNode
*tabNode
= layer
->First();
620 wxTabControl
*tab
= (wxTabControl
*)tabNode
->Data();
621 controls
.Append(tab
);
622 wxNode
*next
= tabNode
->Next();
626 wxNode
*nextLayerNode
= layerNode
->Next();
629 layerNode
= nextLayerNode
;
632 wxTabControl
*lastTab
= (wxTabControl
*) NULL
;
634 wxTabLayer
*currentLayer
= new wxTabLayer
;
635 m_layers
.Append(currentLayer
);
637 wxNode
*node
= controls
.First();
640 wxTabControl
*tabControl
= (wxTabControl
*)node
->Data();
643 // Start another layer (row).
644 // Tricky choice: can't just check if will be overlapping the edge, because
645 // this happens anyway for 2nd and subsequent rows.
646 // Should check this for 1st row, and then subsequent rows should not exceed 1st
648 if (((currentLayer
== m_layers
.First()->Data()) && ((lastTab
->GetX() + 2*lastTab
->GetWidth() + GetHorizontalTabSpacing())
649 > GetViewRect().width
)) ||
650 ((currentLayer
!= m_layers
.First()->Data()) && (currentLayer
->Number() == ((wxTabLayer
*)m_layers
.First()->Data())->Number())))
652 currentLayer
= new wxTabLayer
;
653 m_layers
.Append(currentLayer
);
654 lastTab
= (wxTabControl
*) NULL
;
658 int layer
= m_layers
.Number() - 1;
660 tabControl
->SetRowPosition(currentLayer
->Number());
661 tabControl
->SetColPosition(layer
);
664 int verticalOffset
= (- GetTopMargin()) - ((layer
+1)*GetTabHeight());
665 // Offset from view top-left
666 int horizontalOffset
= 0;
668 horizontalOffset
= layer
*GetHorizontalTabOffset();
670 horizontalOffset
= lastTab
->GetX() + GetTabWidth() + GetHorizontalTabSpacing();
672 tabControl
->SetPosition(horizontalOffset
, verticalOffset
);
673 tabControl
->SetSize(GetTabWidth(), GetTabHeight());
675 currentLayer
->Append(tabControl
);
676 lastTab
= tabControl
;
681 // Move the selected tab to the bottom
682 wxTabControl
*control
= FindTabControlForId(m_tabSelection
);
684 MoveSelectionTab(control
);
689 void wxTabView::Draw(wxDC
& dc
)
691 // Draw top margin area (beneath tabs and above view area)
692 if (GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR
)
694 dc
.SetPen(*wxTRANSPARENT_PEN
);
695 dc
.SetBrush(*GetBackgroundBrush());
697 // Add 1 because the pen is transparent. Under Motif, may be different.
700 (m_tabViewRect
.y
- m_topMargin
),
701 (m_tabViewRect
.width
+ 1),
706 // Draw layers in reverse order
707 wxNode
*node
= m_layers
.Last();
710 wxTabLayer
*layer
= (wxTabLayer
*)node
->Data();
711 wxNode
*node2
= layer
->First();
714 wxTabControl
*control
= (wxTabControl
*)node2
->Data();
715 control
->OnDraw(dc
, (node2
->Next() == NULL
));
716 node2
= node2
->Next();
719 node
= node
->Previous();
724 if (GetTabStyle() & wxTAB_STYLE_DRAW_BOX
)
726 dc
.SetPen(GetShadowPen());
730 (GetViewRect().x
+ 1),
731 (GetViewRect().y
+ GetViewRect().height
),
732 (GetViewRect().x
+ GetViewRect().width
),
733 (GetViewRect().y
+ GetViewRect().height
)
738 (GetViewRect().x
+ GetViewRect().width
),
739 (GetViewRect().y
- GetTopMargin() + 1),
740 (GetViewRect().x
+ GetViewRect().width
),
741 (GetViewRect().y
+ GetViewRect().height
)
744 dc
.SetPen(wxBLACK_PEN
);
749 (GetViewRect().y
+ GetViewRect().height
+ 1),
750 (GetViewRect().x
+ GetViewRect().width
),
751 (GetViewRect().y
+ GetViewRect().height
+ 1)
756 (GetViewRect().x
+ GetViewRect().width
+ 1),
757 (GetViewRect().y
- GetTopMargin()),
758 (GetViewRect().x
+ GetViewRect().width
+ 1),
759 (GetViewRect().y
+ GetViewRect().height
+ 1)
765 // Process mouse event, return FALSE if we didn't process it
766 bool wxTabView::OnEvent(wxMouseEvent
& event
)
768 if (!event
.LeftDown())
772 event
.Position(&x
, &y
);
774 wxTabControl
*hitControl
= (wxTabControl
*) NULL
;
776 wxNode
*node
= m_layers
.First();
779 wxTabLayer
*layer
= (wxTabLayer
*)node
->Data();
780 wxNode
*node2
= layer
->First();
783 wxTabControl
*control
= (wxTabControl
*)node2
->Data();
784 if (control
->HitTest((int)x
, (int)y
))
786 hitControl
= control
;
787 node
= (wxNode
*) NULL
;
788 node2
= (wxNode
*) NULL
;
791 node2
= node2
->Next();
801 wxTabControl
*currentTab
= FindTabControlForId(m_tabSelection
);
803 if (hitControl
== currentTab
)
806 ChangeTab(hitControl
);
811 bool wxTabView::ChangeTab(wxTabControl
*control
)
813 wxTabControl
*currentTab
= FindTabControlForId(m_tabSelection
);
816 oldTab
= currentTab
->GetId();
818 if (control
== currentTab
)
821 if (m_layers
.Number() == 0)
824 if (!OnTabPreActivate(control
->GetId(), oldTab
))
827 // Move the tab to the bottom
828 MoveSelectionTab(control
);
831 currentTab
->SetSelected(FALSE
);
833 control
->SetSelected(TRUE
);
834 m_tabSelection
= control
->GetId();
836 OnTabActivate(control
->GetId(), oldTab
);
838 // Leave window refresh for the implementing window
843 // Move the selected tab to the bottom layer, if necessary,
844 // without calling app activation code
845 bool wxTabView::MoveSelectionTab(wxTabControl
*control
)
847 if (m_layers
.Number() == 0)
850 wxTabLayer
*firstLayer
= (wxTabLayer
*)m_layers
.First()->Data();
852 // Find what column this tab is at, so we can swap with the one at the bottom.
853 // If we're on the bottom layer, then no need to swap.
854 if (!firstLayer
->Member(control
))
858 wxNode
*thisNode
= FindTabNodeAndColumn(control
, &col
);
861 wxNode
*otherNode
= firstLayer
->Nth(col
);
865 // If this is already in the bottom layer, return now
866 if (otherNode
== thisNode
)
869 wxTabControl
*otherTab
= (wxTabControl
*)otherNode
->Data();
871 // We now have pointers to the tab to be changed to,
872 // and the tab on the first layer. Swap tab structures and
875 int thisX
= control
->GetX();
876 int thisY
= control
->GetY();
877 int thisColPos
= control
->GetColPosition();
878 int otherX
= otherTab
->GetX();
879 int otherY
= otherTab
->GetY();
880 int otherColPos
= otherTab
->GetColPosition();
882 control
->SetPosition(otherX
, otherY
);
883 control
->SetColPosition(otherColPos
);
884 otherTab
->SetPosition(thisX
, thisY
);
885 otherTab
->SetColPosition(thisColPos
);
887 // Swap the data for the nodes
888 thisNode
->SetData(otherTab
);
889 otherNode
->SetData(control
);
894 // Called when a tab is activated
895 void wxTabView::OnTabActivate(int /*activateId*/, int /*deactivateId*/)
899 void wxTabView::SetHighlightColour(const wxColour
& col
)
901 m_highlightColour
= col
;
902 m_highlightPen
= wxThePenList
->FindOrCreatePen(col
, 1, wxSOLID
);
905 void wxTabView::SetShadowColour(const wxColour
& col
)
907 m_shadowColour
= col
;
908 m_shadowPen
= wxThePenList
->FindOrCreatePen(col
, 1, wxSOLID
);
911 void wxTabView::SetBackgroundColour(const wxColour
& col
)
913 m_backgroundColour
= col
;
914 m_backgroundPen
= wxThePenList
->FindOrCreatePen(col
, 1, wxSOLID
);
915 m_backgroundBrush
= wxTheBrushList
->FindOrCreateBrush(col
, wxSOLID
);
918 void wxTabView::SetTabSelection(int sel
, bool activateTool
)
920 int oldSel
= m_tabSelection
;
921 wxTabControl
*control
= FindTabControlForId(sel
);
923 if (!OnTabPreActivate(sel
, oldSel
))
927 control
->SetSelected((sel
!= 0)); // TODO ??
930 wxMessageBox(_("Could not find tab for id"), _("Error"), wxOK
);
934 m_tabSelection
= sel
;
935 MoveSelectionTab(control
);
938 OnTabActivate(sel
, oldSel
);
941 // Find tab control for id
942 wxTabControl
*wxTabView::FindTabControlForId(int id
) const
944 wxNode
*node1
= m_layers
.First();
947 wxTabLayer
*layer
= (wxTabLayer
*)node1
->Data();
948 wxNode
*node2
= layer
->First();
951 wxTabControl
*control
= (wxTabControl
*)node2
->Data();
952 if (control
->GetId() == id
)
954 node2
= node2
->Next();
956 node1
= node1
->Next();
958 return (wxTabControl
*) NULL
;
961 // Find tab control for layer, position (starting from zero)
962 wxTabControl
*wxTabView::FindTabControlForPosition(int layer
, int position
) const
964 wxNode
*node1
= m_layers
.Nth(layer
);
966 return (wxTabControl
*) NULL
;
967 wxTabLayer
*tabLayer
= (wxTabLayer
*)node1
->Data();
968 wxNode
*node2
= tabLayer
->Nth(position
);
970 return (wxTabControl
*) NULL
;
971 return (wxTabControl
*)node2
->Data();
974 // Find the node and the column at which this control is positioned.
975 wxNode
*wxTabView::FindTabNodeAndColumn(wxTabControl
*control
, int *col
) const
977 wxNode
*node1
= m_layers
.First();
980 wxTabLayer
*layer
= (wxTabLayer
*)node1
->Data();
982 wxNode
*node2
= layer
->First();
985 wxTabControl
*cnt
= (wxTabControl
*)node2
->Data();
991 node2
= node2
->Next();
994 node1
= node1
->Next();
996 return (wxNode
*) NULL
;
999 int wxTabView::CalculateTabWidth(int noTabs
, bool adjustView
)
1001 m_tabWidth
= (int)((m_tabViewRect
.width
- ((noTabs
- 1)*GetHorizontalTabSpacing()))/noTabs
);
1004 m_tabViewRect
.width
= noTabs
*m_tabWidth
+ ((noTabs
-1)*GetHorizontalTabSpacing());
1013 IMPLEMENT_CLASS(wxTabbedDialog
, wxDialog
)
1015 BEGIN_EVENT_TABLE(wxTabbedDialog
, wxDialog
)
1016 EVT_CLOSE(wxTabbedDialog::OnCloseWindow
)
1017 EVT_MOUSE_EVENTS(wxTabbedDialog::OnMouseEvent
)
1018 EVT_PAINT(wxTabbedDialog::OnPaint
)
1021 wxTabbedDialog::wxTabbedDialog(wxWindow
*parent
, wxWindowID id
,
1022 const wxString
& title
,
1023 const wxPoint
& pos
, const wxSize
& size
,
1024 long windowStyle
, const wxString
& name
):
1025 wxDialog(parent
, id
, title
, pos
, size
, windowStyle
, name
)
1027 m_tabView
= (wxTabView
*) NULL
;
1030 wxTabbedDialog::~wxTabbedDialog(void)
1036 void wxTabbedDialog::OnCloseWindow(wxCloseEvent
& WXUNUSED(event
) )
1041 void wxTabbedDialog::OnMouseEvent(wxMouseEvent
& event
)
1044 m_tabView
->OnEvent(event
);
1047 void wxTabbedDialog::OnPaint(wxPaintEvent
& WXUNUSED(event
) )
1051 m_tabView
->Draw(dc
);
1058 IMPLEMENT_CLASS(wxTabbedPanel
, wxPanel
)
1060 BEGIN_EVENT_TABLE(wxTabbedPanel
, wxPanel
)
1061 EVT_MOUSE_EVENTS(wxTabbedPanel::OnMouseEvent
)
1062 EVT_PAINT(wxTabbedPanel::OnPaint
)
1065 wxTabbedPanel::wxTabbedPanel(wxWindow
*parent
, wxWindowID id
, const wxPoint
& pos
,
1066 const wxSize
& size
, long windowStyle
, const wxString
& name
):
1067 wxPanel(parent
, id
, pos
, size
, windowStyle
, name
)
1069 m_tabView
= (wxTabView
*) NULL
;
1072 wxTabbedPanel::~wxTabbedPanel(void)
1077 void wxTabbedPanel::OnMouseEvent(wxMouseEvent
& event
)
1080 m_tabView
->OnEvent(event
);
1083 void wxTabbedPanel::OnPaint(wxPaintEvent
& WXUNUSED(event
) )
1087 m_tabView
->Draw(dc
);
1094 IMPLEMENT_CLASS(wxPanelTabView
, wxTabView
)
1096 wxPanelTabView::wxPanelTabView(wxPanel
*pan
, long style
): wxTabView(style
), m_tabWindows(wxKEY_INTEGER
)
1099 m_currentWindow
= (wxWindow
*) NULL
;
1101 if (m_panel
->IsKindOf(CLASSINFO(wxTabbedDialog
)))
1102 ((wxTabbedDialog
*)m_panel
)->SetTabView(this);
1103 else if (m_panel
->IsKindOf(CLASSINFO(wxTabbedPanel
)))
1104 ((wxTabbedPanel
*)m_panel
)->SetTabView(this);
1109 wxPanelTabView::~wxPanelTabView(void)
1114 // Called when a tab is activated
1115 void wxPanelTabView::OnTabActivate(int activateId
, int deactivateId
)
1120 wxWindow
*oldWindow
= ((deactivateId
== -1) ? 0 : GetTabWindow(deactivateId
));
1121 wxWindow
*newWindow
= GetTabWindow(activateId
);
1124 oldWindow
->Show(FALSE
);
1126 newWindow
->Show(TRUE
);
1132 void wxPanelTabView::AddTabWindow(int id
, wxWindow
*window
)
1134 m_tabWindows
.Append((long)id
, window
);
1135 window
->Show(FALSE
);
1138 wxWindow
*wxPanelTabView::GetTabWindow(int id
) const
1140 wxNode
*node
= m_tabWindows
.Find((long)id
);
1142 return (wxWindow
*) NULL
;
1143 return (wxWindow
*)node
->Data();
1146 void wxPanelTabView::ClearWindows(bool deleteWindows
)
1149 m_tabWindows
.DeleteContents(TRUE
);
1150 m_tabWindows
.Clear();
1151 m_tabWindows
.DeleteContents(FALSE
);
1154 void wxPanelTabView::ShowWindowForTab(int id
)
1156 wxWindow
*newWindow
= GetTabWindow(id
);
1157 if (newWindow
== m_currentWindow
)
1159 if (m_currentWindow
)
1160 m_currentWindow
->Show(FALSE
);
1161 newWindow
->Show(TRUE
);
1162 newWindow
->Refresh();