/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/tabg.cpp
ViewVC logotype

Annotation of /branch/r3113_0.9.7_beta/3rdparty/wxWidgets/src/generic/tabg.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.22