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