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