X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/4b5f3fe655deeb91d5d3abe8fad30c4a1cae63dc..98cb8dcb0cf3b0e660f1f67e1c02451ab10257de:/src/generic/tabg.cpp diff --git a/src/generic/tabg.cpp b/src/generic/tabg.cpp index 5adc584c4c..249395811a 100644 --- a/src/generic/tabg.cpp +++ b/src/generic/tabg.cpp @@ -6,13 +6,9 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "tabg.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -20,16 +16,23 @@ #pragma hdrstop #endif +#if wxUSE_TAB_DIALOG + #ifndef WX_PRECOMP -#include "wx/wx.h" + #include "wx/settings.h" + #include "wx/intl.h" + #include "wx/dcclient.h" #endif #include #include #include -#include +#include "wx/math.h" #include "wx/tab.h" +#include "wx/listimpl.cpp" + +WX_DEFINE_LIST(wxTabLayerList) // not defined: use old, square tab implementation (fills in tabs) // defined: use new, rounded tab implementation (doesn't colour in tabs) @@ -37,13 +40,12 @@ IMPLEMENT_DYNAMIC_CLASS(wxTabControl, wxObject) -IMPLEMENT_DYNAMIC_CLASS(wxTabLayer, wxList) +// IMPLEMENT_DYNAMIC_CLASS(wxTabLayer, wxList) wxTabControl::wxTabControl(wxTabView *v) { m_view = v; - m_isSelected = FALSE; - m_labelFont = (wxFont *) NULL; + m_isSelected = false; m_offsetX = 0; m_offsetY = 0; m_width = 0; @@ -56,18 +58,18 @@ wxTabControl::wxTabControl(wxTabView *v) wxTabControl::~wxTabControl(void) { } - + void wxTabControl::OnDraw(wxDC& dc, bool lastInRow) { // Old, but in some ways better (drawing opaque tabs) #ifndef wxUSE_NEW_METHOD if (!m_view) return; - + // Top-left of tab view area int viewX = m_view->GetViewRect().x; int viewY = m_view->GetViewRect().y; - + // Top-left of tab control int tabX = GetX() + viewX; int tabY = GetY() + viewY; @@ -77,7 +79,7 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow) tabHeightInc = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight()); tabY -= tabHeightInc; } - + dc.SetPen(*wxTRANSPARENT_PEN); // Draw grey background @@ -86,9 +88,13 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow) dc.SetBrush(*m_view->GetBackgroundBrush()); // Add 1 because the pen is transparent. Under Motif, may be different. +#ifdef __WXMOTIF__ + dc.DrawRectangle(tabX, tabY, (GetWidth()+1), (GetHeight() + tabHeightInc)); +#else dc.DrawRectangle(tabX, tabY, (GetWidth()+1), (GetHeight() + 1 + tabHeightInc)); +#endif } - + // Draw highlight and shadow dc.SetPen(*m_view->GetHighlightPen()); @@ -143,15 +149,19 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow) if (lastInRow) { // 25/5/97 UNLESS it's less than the max number of positions in this row - + int topY = m_view->GetViewRect().y - m_view->GetTopMargin(); - int maxPositions = ((wxTabLayer *)m_view->GetLayers().Nth(0)->Data())->Number(); + int maxPositions = ((wxTabLayer *)m_view->GetLayers().Item(0)->GetData())->GetCount(); // Only down to the bottom of the tab, not to the top of the view if ( GetRowPosition() < (maxPositions - 1) ) topY = tabY + GetHeight() + tabHeightInc; +#ifdef __WXMOTIF__ + topY -= 1; +#endif + // Shadow dc.DrawLine((tabX + GetWidth()), tabY, (tabX + GetWidth()), topY); // Draw black line to emphasize shadow @@ -170,6 +180,10 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow) if (tabBeneath && tabBeneath->IsSelected()) subtractThis = (m_view->GetTabSelectionHeight() - m_view->GetTabHeight()); +#ifdef __WXMOTIF__ + subtractThis += 1; +#endif + // Draw only to next tab down. dc.DrawLine((tabX + GetWidth()), tabY, (tabX + GetWidth()), (tabY + GetHeight() + tabHeightInc - subtractThis)); @@ -180,14 +194,14 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow) (tabY + GetHeight() + tabHeightInc - subtractThis)); } } - + // Draw centered text int textY = tabY + m_view->GetVerticalTabTextSpacing() + tabHeightInc; if (m_isSelected) - dc.SetFont(*m_view->GetSelectedTabFont()); + dc.SetFont(* m_view->GetSelectedTabFont()); else - dc.SetFont(*GetFont()); + dc.SetFont(* GetFont()); wxColour col(m_view->GetTextColour()); dc.SetTextForeground(col); @@ -196,7 +210,12 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow) dc.GetTextExtent(GetLabel(), &textWidth, &textHeight); int textX = (int)(tabX + (GetWidth() - textWidth)/2.0); + if (textX < (tabX + 2)) + textX = (tabX + 2); + + dc.SetClippingRegion(tabX, tabY, GetWidth(), GetHeight()); dc.DrawText(GetLabel(), textX, textY); + dc.DestroyClippingRegion(); if (m_isSelected) { @@ -213,258 +232,258 @@ void wxTabControl::OnDraw(wxDC& dc, bool lastInRow) #else // New HEL version with rounder tabs - if (!m_view) return; - - int tabInc = 0; - if (m_isSelected) - { - tabInc = m_view->GetTabSelectionHeight() - m_view->GetTabHeight(); - } - int tabLeft = GetX() + m_view->GetViewRect().x; - int tabTop = GetY() + m_view->GetViewRect().y - tabInc; - int tabRight = tabLeft + m_view->GetTabWidth(); - int left = m_view->GetViewRect().x; - int top = tabTop + m_view->GetTabHeight() + tabInc; - int right = left + m_view->GetViewRect().width; - int bottom = top + m_view->GetViewRect().height; - - if (m_isSelected) - { - // TAB is selected - draw TAB and the View's full outline - - dc.SetPen(*(m_view->GetHighlightPen())); - wxPoint pnts[10]; - int n = 0; - pnts[n].x = left; pnts[n++].y = bottom; - pnts[n].x = left; pnts[n++].y = top; - pnts[n].x = tabLeft; pnts[n++].y = top; - pnts[n].x = tabLeft; pnts[n++].y = tabTop + 2; - pnts[n].x = tabLeft + 2; pnts[n++].y = tabTop; - pnts[n].x = tabRight - 1; pnts[n++].y = tabTop; - dc.DrawLines(n, pnts); - if (!lastInRow) - { - dc.DrawLine( - (tabRight + 2), - top, - right, - top - ); - } - - dc.SetPen(*(m_view->GetShadowPen())); - dc.DrawLine( - tabRight, - tabTop + 2, - tabRight, - top - ); - dc.DrawLine( - right, - top, - right, - bottom - ); - dc.DrawLine( - right, - bottom, - left, - bottom - ); - - dc.SetPen(*wxBLACK_PEN); - dc.DrawPoint( - tabRight, - tabTop + 1 - ); - dc.DrawPoint( - tabRight + 1, - tabTop + 2 - ); - if (lastInRow) - { - dc.DrawLine( - tabRight + 1, - bottom, - tabRight + 1, - tabTop + 1 - ); - } - else - { - dc.DrawLine( - tabRight + 1, - tabTop + 2, - tabRight + 1, - top - ); - dc.DrawLine( - right + 1, - top, - right + 1, - bottom + 1 - ); - } - dc.DrawLine( - right + 1, - bottom + 1, - left + 1, - bottom + 1 - ); - } - else - { - // TAB is not selected - just draw TAB outline and RH edge - // if the TAB is the last in the row - - int maxPositions = ((wxTabLayer*)m_view->GetLayers().Nth(0)->Data())->Number(); - wxTabControl* tabBelow = 0; - wxTabControl* tabBelowRight = 0; - if (GetColPosition() > 0) - { - tabBelow = m_view->FindTabControlForPosition( - GetColPosition() - 1, - GetRowPosition() - ); - } - if (!lastInRow && GetColPosition() > 0) - { - tabBelowRight = m_view->FindTabControlForPosition( - GetColPosition() - 1, - GetRowPosition() + 1 - ); - } - - float raisedTop = top - m_view->GetTabSelectionHeight() + - m_view->GetTabHeight(); - - dc.SetPen(*(m_view->GetHighlightPen())); - wxPoint pnts[10]; - int n = 0; - - pnts[n].x = tabLeft; - - if (tabBelow && tabBelow->IsSelected()) - { - pnts[n++].y = (long)raisedTop; - } - else - { - pnts[n++].y = top; - } - pnts[n].x = tabLeft; pnts[n++].y = tabTop + 2; - pnts[n].x = tabLeft + 2; pnts[n++].y = tabTop; - pnts[n].x = tabRight - 1; pnts[n++].y = tabTop; - dc.DrawLines(n, pnts); - - dc.SetPen(*(m_view->GetShadowPen())); - if (GetRowPosition() >= maxPositions - 1) - { - dc.DrawLine( - tabRight, - (tabTop + 2), - tabRight, - bottom - ); - dc.DrawLine( - tabRight, - bottom, - (tabRight - m_view->GetHorizontalTabOffset()), - bottom - ); - } - else - { - if (tabBelowRight && tabBelowRight->IsSelected()) - { - dc.DrawLine( - tabRight, - (long)raisedTop, - tabRight, - tabTop + 1 - ); - } - else - { - dc.DrawLine( - tabRight, - top - 1, - tabRight, - tabTop + 1 - ); - } - } - - dc.SetPen(*wxBLACK_PEN); - dc.DrawPoint( - tabRight, - tabTop + 1 - ); - dc.DrawPoint( - tabRight + 1, - tabTop + 2 - ); - if (GetRowPosition() >= maxPositions - 1) - { - // draw right hand edge to bottom of view - dc.DrawLine( - tabRight + 1, - bottom + 1, - tabRight + 1, - tabTop + 2 - ); - dc.DrawLine( - tabRight + 1, - bottom + 1, - (tabRight - m_view->GetHorizontalTabOffset()), - bottom + 1 - ); - } - else - { - // draw right hand edge of TAB - if (tabBelowRight && tabBelowRight->IsSelected()) - { - dc.DrawLine( - tabRight + 1, - (long)(raisedTop - 1), - tabRight + 1, - tabTop + 2 - ); - } - else - { - dc.DrawLine( - tabRight + 1, - top - 1, - tabRight + 1, - tabTop + 2 - ); - } - } - } - - // Draw centered text - dc.SetPen(*wxBLACK_PEN); - if (m_isSelected) - { - dc.SetFont(*(m_view->GetSelectedTabFont())); - } - else - { - dc.SetFont(*(GetFont())); - } - - wxColour col(m_view->GetTextColour()); - dc.SetTextForeground(col); - dc.SetBackgroundMode(wxTRANSPARENT); - long textWidth, textHeight; - dc.GetTextExtent(GetLabel(), &textWidth, &textHeight); - - float textX = (tabLeft + tabRight - textWidth) / 2; - float textY = (tabInc + tabTop + m_view->GetVerticalTabTextSpacing()); - - dc.DrawText(GetLabel(), (long)textX, (long)textY); + if (!m_view) return; + + int tabInc = 0; + if (m_isSelected) + { + tabInc = m_view->GetTabSelectionHeight() - m_view->GetTabHeight(); + } + int tabLeft = GetX() + m_view->GetViewRect().x; + int tabTop = GetY() + m_view->GetViewRect().y - tabInc; + int tabRight = tabLeft + m_view->GetTabWidth(); + int left = m_view->GetViewRect().x; + int top = tabTop + m_view->GetTabHeight() + tabInc; + int right = left + m_view->GetViewRect().width; + int bottom = top + m_view->GetViewRect().height; + + if (m_isSelected) + { + // TAB is selected - draw TAB and the View's full outline + + dc.SetPen(*(m_view->GetHighlightPen())); + wxPoint pnts[10]; + int n = 0; + pnts[n].x = left; pnts[n++].y = bottom; + pnts[n].x = left; pnts[n++].y = top; + pnts[n].x = tabLeft; pnts[n++].y = top; + pnts[n].x = tabLeft; pnts[n++].y = tabTop + 2; + pnts[n].x = tabLeft + 2; pnts[n++].y = tabTop; + pnts[n].x = tabRight - 1; pnts[n++].y = tabTop; + dc.DrawLines(n, pnts); + if (!lastInRow) + { + dc.DrawLine( + (tabRight + 2), + top, + right, + top + ); + } + + dc.SetPen(*(m_view->GetShadowPen())); + dc.DrawLine( + tabRight, + tabTop + 2, + tabRight, + top + ); + dc.DrawLine( + right, + top, + right, + bottom + ); + dc.DrawLine( + right, + bottom, + left, + bottom + ); + + dc.SetPen(*wxBLACK_PEN); + dc.DrawPoint( + tabRight, + tabTop + 1 + ); + dc.DrawPoint( + tabRight + 1, + tabTop + 2 + ); + if (lastInRow) + { + dc.DrawLine( + tabRight + 1, + bottom, + tabRight + 1, + tabTop + 1 + ); + } + else + { + dc.DrawLine( + tabRight + 1, + tabTop + 2, + tabRight + 1, + top + ); + dc.DrawLine( + right + 1, + top, + right + 1, + bottom + 1 + ); + } + dc.DrawLine( + right + 1, + bottom + 1, + left + 1, + bottom + 1 + ); + } + else + { + // TAB is not selected - just draw TAB outline and RH edge + // if the TAB is the last in the row + + int maxPositions = ((wxTabLayer*)m_view->GetLayers().Item(0)->GetData())->GetCount(); + wxTabControl* tabBelow = 0; + wxTabControl* tabBelowRight = 0; + if (GetColPosition() > 0) + { + tabBelow = m_view->FindTabControlForPosition( + GetColPosition() - 1, + GetRowPosition() + ); + } + if (!lastInRow && GetColPosition() > 0) + { + tabBelowRight = m_view->FindTabControlForPosition( + GetColPosition() - 1, + GetRowPosition() + 1 + ); + } + + float raisedTop = top - m_view->GetTabSelectionHeight() + + m_view->GetTabHeight(); + + dc.SetPen(*(m_view->GetHighlightPen())); + wxPoint pnts[10]; + int n = 0; + + pnts[n].x = tabLeft; + + if (tabBelow && tabBelow->IsSelected()) + { + pnts[n++].y = (long)raisedTop; + } + else + { + pnts[n++].y = top; + } + pnts[n].x = tabLeft; pnts[n++].y = tabTop + 2; + pnts[n].x = tabLeft + 2; pnts[n++].y = tabTop; + pnts[n].x = tabRight - 1; pnts[n++].y = tabTop; + dc.DrawLines(n, pnts); + + dc.SetPen(*(m_view->GetShadowPen())); + if (GetRowPosition() >= maxPositions - 1) + { + dc.DrawLine( + tabRight, + (tabTop + 2), + tabRight, + bottom + ); + dc.DrawLine( + tabRight, + bottom, + (tabRight - m_view->GetHorizontalTabOffset()), + bottom + ); + } + else + { + if (tabBelowRight && tabBelowRight->IsSelected()) + { + dc.DrawLine( + tabRight, + (long)raisedTop, + tabRight, + tabTop + 1 + ); + } + else + { + dc.DrawLine( + tabRight, + top - 1, + tabRight, + tabTop + 1 + ); + } + } + + dc.SetPen(*wxBLACK_PEN); + dc.DrawPoint( + tabRight, + tabTop + 1 + ); + dc.DrawPoint( + tabRight + 1, + tabTop + 2 + ); + if (GetRowPosition() >= maxPositions - 1) + { + // draw right hand edge to bottom of view + dc.DrawLine( + tabRight + 1, + bottom + 1, + tabRight + 1, + tabTop + 2 + ); + dc.DrawLine( + tabRight + 1, + bottom + 1, + (tabRight - m_view->GetHorizontalTabOffset()), + bottom + 1 + ); + } + else + { + // draw right hand edge of TAB + if (tabBelowRight && tabBelowRight->IsSelected()) + { + dc.DrawLine( + tabRight + 1, + (long)(raisedTop - 1), + tabRight + 1, + tabTop + 2 + ); + } + else + { + dc.DrawLine( + tabRight + 1, + top - 1, + tabRight + 1, + tabTop + 2 + ); + } + } + } + + // Draw centered text + dc.SetPen(*wxBLACK_PEN); + if (m_isSelected) + { + dc.SetFont(*(m_view->GetSelectedTabFont())); + } + else + { + dc.SetFont(*(GetFont())); + } + + wxColour col(m_view->GetTextColour()); + dc.SetTextForeground(col); + dc.SetBackgroundMode(wxTRANSPARENT); + long textWidth, textHeight; + dc.GetTextExtent(GetLabel(), &textWidth, &textHeight); + + float textX = (tabLeft + tabRight - textWidth) / 2; + float textY = (tabInc + tabTop + m_view->GetVerticalTabTextSpacing()); + + dc.DrawText(GetLabel(), (long)textX, (long)textY); #endif } @@ -477,11 +496,11 @@ bool wxTabControl::HitTest(int x, int y) const // Bottom-right int tabX2 = tabX1 + GetWidth(); int tabY2 = tabY1 + GetHeight(); - + if (x >= tabX1 && y >= tabY1 && x <= tabX2 && y <= tabY2) - return TRUE; + return true; else - return FALSE; + return false; } IMPLEMENT_DYNAMIC_CLASS(wxTabView, wxObject) @@ -504,21 +523,21 @@ wxTabView::wxTabView(long style) m_tabViewRect.x = 300; m_highlightColour = *wxWHITE; m_shadowColour = wxColour(128, 128, 128); - m_backgroundColour = *wxLIGHT_GREY; + m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); m_textColour = *wxBLACK; m_highlightPen = wxWHITE_PEN; m_shadowPen = wxGREY_PEN; - m_backgroundPen = wxLIGHT_GREY_PEN; - m_backgroundBrush = wxLIGHT_GREY_BRUSH; - m_tabFont = wxTheFontList->FindOrCreateFont(9, wxSWISS, wxNORMAL, wxNORMAL); - m_tabSelectedFont = wxTheFontList->FindOrCreateFont(9, wxSWISS, wxNORMAL, wxBOLD); + SetBackgroundColour(m_backgroundColour); + m_tabFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + m_tabSelectedFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); m_window = (wxWindow *) NULL; } wxTabView::~wxTabView() { + ClearTabs(true); } - + // Automatically positions tabs // TODO: this should just add the tab to a list, and then // a layout function (e.g. Realize) should be called when all tabs have been added. @@ -526,7 +545,7 @@ wxTabView::~wxTabView() wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *existingTab) { // First, find which layer we should be adding to. - wxNode *node = m_layers.Last(); + wxTabLayerList::compatibility_iterator node = m_layers.GetLast(); if (!node) { wxTabLayer *newLayer = new wxTabLayer; @@ -534,37 +553,37 @@ wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *exi } // Check if adding another tab control would go off the // right-hand edge of the layer. - wxTabLayer *tabLayer = (wxTabLayer *)node->Data(); - wxNode *lastTabNode = tabLayer->Last(); + wxTabLayer *tabLayer = (wxTabLayer *)node->GetData(); + wxList::compatibility_iterator lastTabNode = tabLayer->GetLast(); if (lastTabNode) { - wxTabControl *lastTab = (wxTabControl *)lastTabNode->Data(); + wxTabControl *lastTab = (wxTabControl *)lastTabNode->GetData(); // Start another layer (row). // Tricky choice: can't just check if will be overlapping the edge, because // this happens anyway for 2nd and subsequent rows. // Should check this for 1st row, and then subsequent rows should not exceed 1st // in length. - if (((tabLayer == m_layers.First()->Data()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing()) + if (((tabLayer == m_layers.GetFirst()->GetData()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing()) > GetViewRect().width)) || - ((tabLayer != m_layers.First()->Data()) && (tabLayer->Number() == ((wxTabLayer *)m_layers.First()->Data())->Number()))) + ((tabLayer != m_layers.GetFirst()->GetData()) && (tabLayer->GetCount() == ((wxTabLayer *)m_layers.GetFirst()->GetData())->GetCount()))) { tabLayer = new wxTabLayer; m_layers.Append(tabLayer); - lastTabNode = (wxNode *) NULL; + lastTabNode = wxList::compatibility_iterator(); } } - int layer = m_layers.Number() - 1; - + int layer = m_layers.GetCount() - 1; + wxTabControl *tabControl = existingTab; if (!existingTab) tabControl = OnCreateTabControl(); - tabControl->SetRowPosition(tabLayer->Number()); + tabControl->SetRowPosition(tabLayer->GetCount()); tabControl->SetColPosition(layer); - + wxTabControl *lastTab = (wxTabControl *) NULL; if (lastTabNode) - lastTab = (wxTabControl *)lastTabNode->Data(); - + lastTab = (wxTabControl *)lastTabNode->GetData(); + // Top of new tab int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight()); // Offset from view top-left @@ -573,40 +592,88 @@ wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *exi horizontalOffset = layer*GetHorizontalTabOffset(); else horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing(); - + tabControl->SetPosition(horizontalOffset, verticalOffset); tabControl->SetSize(GetTabWidth(), GetTabHeight()); tabControl->SetId(id); tabControl->SetLabel(label); - tabControl->SetFont(GetTabFont()); - + tabControl->SetFont(* GetTabFont()); + tabLayer->Append(tabControl); m_noTabs ++; - + return tabControl; } - + +// Remove the tab without deleting the window +bool wxTabView::RemoveTab(int id) +{ + wxTabLayerList::compatibility_iterator layerNode = m_layers.GetFirst(); + while (layerNode) + { + wxTabLayer *layer = (wxTabLayer *)layerNode->GetData(); + wxList::compatibility_iterator tabNode = layer->GetFirst(); + while (tabNode) + { + wxTabControl *tab = (wxTabControl *)tabNode->GetData(); + if (tab->GetId() == id) + { + if (id == m_tabSelection) + m_tabSelection = -1; + delete tab; + layer->Erase(tabNode); + m_noTabs --; + + // The layout has changed + LayoutTabs(); + return true; + } + tabNode = tabNode->GetNext(); + } + layerNode = layerNode->GetNext(); + } + return false; +} + +bool wxTabView::SetTabText(int id, const wxString& label) +{ + wxTabControl* control = FindTabControlForId(id); + if (!control) + return false; + control->SetLabel(label); + return true; +} + +wxString wxTabView::GetTabText(int id) const +{ + wxTabControl* control = FindTabControlForId(id); + if (!control) + return wxEmptyString; + else + return control->GetLabel(); +} + // Returns the total height of the tabs component -- this may be several // times the height of a tab, if there are several tab layers (rows). int wxTabView::GetTotalTabHeight() { int minY = 0; - wxNode *layerNode = m_layers.First(); + wxTabLayerList::compatibility_iterator layerNode = m_layers.GetFirst(); while (layerNode) { - wxTabLayer *layer = (wxTabLayer *)layerNode->Data(); - wxNode *tabNode = layer->First(); + wxTabLayer *layer = (wxTabLayer *)layerNode->GetData(); + wxList::compatibility_iterator tabNode = layer->GetFirst(); while (tabNode) { - wxTabControl *tab = (wxTabControl *)tabNode->Data(); + wxTabControl *tab = (wxTabControl *)tabNode->GetData(); if (tab->GetY() < minY) minY = tab->GetY(); - tabNode = tabNode->Next(); + tabNode = tabNode->GetNext(); } - layerNode = layerNode->Next(); + layerNode = layerNode->GetNext(); } return - minY; @@ -614,62 +681,64 @@ int wxTabView::GetTotalTabHeight() void wxTabView::ClearTabs(bool deleteTabs) { - wxNode *layerNode = m_layers.First(); + wxTabLayerList::compatibility_iterator layerNode = m_layers.GetFirst(); while (layerNode) { - wxTabLayer *layer = (wxTabLayer *)layerNode->Data(); - wxNode *tabNode = layer->First(); + wxTabLayer *layer = (wxTabLayer *)layerNode->GetData(); + wxList::compatibility_iterator tabNode = layer->GetFirst(); while (tabNode) { - wxTabControl *tab = (wxTabControl *)tabNode->Data(); + wxTabControl *tab = (wxTabControl *)tabNode->GetData(); if (deleteTabs) delete tab; - wxNode *next = tabNode->Next(); - delete tabNode; + wxList::compatibility_iterator next = tabNode->GetNext(); + layer->Erase(tabNode); tabNode = next; } - wxNode *nextLayerNode = layerNode->Next(); + wxTabLayerList::compatibility_iterator nextLayerNode = layerNode->GetNext(); delete layer; - delete layerNode; + m_layers.Erase(layerNode); layerNode = nextLayerNode; } + m_noTabs = 0; + m_tabSelection = -1; } // Layout tabs (optional, e.g. if resizing window) -void wxTabView::Layout(void) +void wxTabView::LayoutTabs(void) { // Make a list of the tab controls, deleting the wxTabLayers. wxList controls; - wxNode *layerNode = m_layers.First(); + wxTabLayerList::compatibility_iterator layerNode = m_layers.GetFirst(); while (layerNode) { - wxTabLayer *layer = (wxTabLayer *)layerNode->Data(); - wxNode *tabNode = layer->First(); + wxTabLayer *layer = (wxTabLayer *)layerNode->GetData(); + wxList::compatibility_iterator tabNode = layer->GetFirst(); while (tabNode) { - wxTabControl *tab = (wxTabControl *)tabNode->Data(); + wxTabControl *tab = (wxTabControl *)tabNode->GetData(); controls.Append(tab); - wxNode *next = tabNode->Next(); - delete tabNode; + wxList::compatibility_iterator next = tabNode->GetNext(); + layer->Erase(tabNode); tabNode = next; } - wxNode *nextLayerNode = layerNode->Next(); + wxTabLayerList::compatibility_iterator nextLayerNode = layerNode->GetNext(); delete layer; - delete layerNode; + m_layers.Erase(layerNode); layerNode = nextLayerNode; } - + wxTabControl *lastTab = (wxTabControl *) NULL; - + wxTabLayer *currentLayer = new wxTabLayer; m_layers.Append(currentLayer); - - wxNode *node = controls.First(); + + wxList::compatibility_iterator node = controls.GetFirst(); while (node) { - wxTabControl *tabControl = (wxTabControl *)node->Data(); + wxTabControl *tabControl = (wxTabControl *)node->GetData(); if (lastTab) { // Start another layer (row). @@ -677,21 +746,21 @@ void wxTabView::Layout(void) // this happens anyway for 2nd and subsequent rows. // Should check this for 1st row, and then subsequent rows should not exceed 1st // in length. - if (((currentLayer == m_layers.First()->Data()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing()) + if (((currentLayer == m_layers.GetFirst()->GetData()) && ((lastTab->GetX() + 2*lastTab->GetWidth() + GetHorizontalTabSpacing()) > GetViewRect().width)) || - ((currentLayer != m_layers.First()->Data()) && (currentLayer->Number() == ((wxTabLayer *)m_layers.First()->Data())->Number()))) + ((currentLayer != m_layers.GetFirst()->GetData()) && (currentLayer->GetCount() == ((wxTabLayer *)m_layers.GetFirst()->GetData())->GetCount()))) { currentLayer = new wxTabLayer; m_layers.Append(currentLayer); lastTab = (wxTabControl *) NULL; } } - - int layer = m_layers.Number() - 1; - tabControl->SetRowPosition(currentLayer->Number()); + int layer = m_layers.GetCount() - 1; + + tabControl->SetRowPosition(currentLayer->GetCount()); tabControl->SetColPosition(layer); - + // Top of new tab int verticalOffset = (- GetTopMargin()) - ((layer+1)*GetTabHeight()); // Offset from view top-left @@ -700,14 +769,14 @@ void wxTabView::Layout(void) horizontalOffset = layer*GetHorizontalTabOffset(); else horizontalOffset = lastTab->GetX() + GetTabWidth() + GetHorizontalTabSpacing(); - + tabControl->SetPosition(horizontalOffset, verticalOffset); tabControl->SetSize(GetTabWidth(), GetTabHeight()); currentLayer->Append(tabControl); lastTab = tabControl; - node = node->Next(); + node = node->GetNext(); } // Move the selected tab to the bottom @@ -720,124 +789,133 @@ void wxTabView::Layout(void) // Draw all tabs void wxTabView::Draw(wxDC& dc) { - // Draw top margin area (beneath tabs and above view area) - if (GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR) - { - dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(*GetBackgroundBrush()); - - // Add 1 because the pen is transparent. Under Motif, may be different. - dc.DrawRectangle( - m_tabViewRect.x, - (m_tabViewRect.y - m_topMargin), - (m_tabViewRect.width + 1), - (m_topMargin + 1) - ); - } - - // Draw layers in reverse order - wxNode *node = m_layers.Last(); - while (node) - { - wxTabLayer *layer = (wxTabLayer *)node->Data(); - wxNode *node2 = layer->First(); - while (node2) - { - wxTabControl *control = (wxTabControl *)node2->Data(); - control->OnDraw(dc, (node2->Next() == NULL)); - node2 = node2->Next(); - } - - node = node->Previous(); - } + // Don't draw anything if there are no tabs. + if (GetNumberOfTabs() == 0) + return; + + // Draw top margin area (beneath tabs and above view area) + if (GetTabStyle() & wxTAB_STYLE_COLOUR_INTERIOR) + { + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush(*GetBackgroundBrush()); + + // Add 1 because the pen is transparent. Under Motif, may be different. + dc.DrawRectangle( + m_tabViewRect.x, + (m_tabViewRect.y - m_topMargin), + (m_tabViewRect.width + 1), + (m_topMargin + 1) + ); + } + + // Draw layers in reverse order + wxTabLayerList::compatibility_iterator node = m_layers.GetLast(); + while (node) + { + wxTabLayer *layer = (wxTabLayer *)node->GetData(); + wxList::compatibility_iterator node2 = layer->GetFirst(); + while (node2) + { + wxTabControl *control = (wxTabControl *)node2->GetData(); + control->OnDraw(dc, (!node2->GetNext())); + node2 = node2->GetNext(); + } + + node = node->GetPrevious(); + } #ifndef wxUSE_NEW_METHOD - if (GetTabStyle() & wxTAB_STYLE_DRAW_BOX) - { - dc.SetPen(GetShadowPen()); - - // Draw bottom line - dc.DrawLine( - (GetViewRect().x + 1), - (GetViewRect().y + GetViewRect().height), - (GetViewRect().x + GetViewRect().width + 1), - (GetViewRect().y + GetViewRect().height) - ); - - // Draw right line - dc.DrawLine( - (GetViewRect().x + GetViewRect().width), - (GetViewRect().y - GetTopMargin() + 1), - (GetViewRect().x + GetViewRect().width), - (GetViewRect().y + GetViewRect().height) - ); - - dc.SetPen(wxBLACK_PEN); - - // Draw bottom line - dc.DrawLine( - (GetViewRect().x), - (GetViewRect().y + GetViewRect().height + 1), - (GetViewRect().x + GetViewRect().width + 2), - (GetViewRect().y + GetViewRect().height + 1) - ); - - // Draw right line - dc.DrawLine( - (GetViewRect().x + GetViewRect().width + 1), - (GetViewRect().y - GetTopMargin()), - (GetViewRect().x + GetViewRect().width + 1), - (GetViewRect().y + GetViewRect().height + 1) - ); - } + if (GetTabStyle() & wxTAB_STYLE_DRAW_BOX) + { + dc.SetPen(* GetShadowPen()); + + // Draw bottom line + dc.DrawLine( + (GetViewRect().x + 1), + (GetViewRect().y + GetViewRect().height), + (GetViewRect().x + GetViewRect().width + 1), + (GetViewRect().y + GetViewRect().height) + ); + + // Draw right line + dc.DrawLine( + (GetViewRect().x + GetViewRect().width), + (GetViewRect().y - GetTopMargin() + 1), + (GetViewRect().x + GetViewRect().width), + (GetViewRect().y + GetViewRect().height) + ); + + dc.SetPen(* wxBLACK_PEN); + + // Draw bottom line + dc.DrawLine( + (GetViewRect().x), + (GetViewRect().y + GetViewRect().height + 1), +#if defined(__WXMOTIF__) + (GetViewRect().x + GetViewRect().width + 1), +#else + (GetViewRect().x + GetViewRect().width + 2), +#endif + + (GetViewRect().y + GetViewRect().height + 1) + ); + + // Draw right line + dc.DrawLine( + (GetViewRect().x + GetViewRect().width + 1), + (GetViewRect().y - GetTopMargin()), + (GetViewRect().x + GetViewRect().width + 1), + (GetViewRect().y + GetViewRect().height + 1) + ); + } #endif } - -// Process mouse event, return FALSE if we didn't process it + +// Process mouse event, return false if we didn't process it bool wxTabView::OnEvent(wxMouseEvent& event) { if (!event.LeftDown()) - return FALSE; - - float x, y; - event.Position(&x, &y); - + return false; + + wxCoord x, y; + event.GetPosition(&x, &y); + wxTabControl *hitControl = (wxTabControl *) NULL; - - wxNode *node = m_layers.First(); + + wxTabLayerList::compatibility_iterator node = m_layers.GetFirst(); while (node) { - wxTabLayer *layer = (wxTabLayer *)node->Data(); - wxNode *node2 = layer->First(); + wxTabLayer *layer = (wxTabLayer *)node->GetData(); + wxList::compatibility_iterator node2 = layer->GetFirst(); while (node2) { - wxTabControl *control = (wxTabControl *)node2->Data(); + wxTabControl *control = (wxTabControl *)node2->GetData(); if (control->HitTest((int)x, (int)y)) { hitControl = control; - node = (wxNode *) NULL; - node2 = (wxNode *) NULL; + node = wxTabLayerList::compatibility_iterator(); + node2 = wxList::compatibility_iterator(); } else - node2 = node2->Next(); + node2 = node2->GetNext(); } - + if (node) - node = node->Next(); + node = node->GetNext(); } - + if (!hitControl) - return FALSE; - + return false; + wxTabControl *currentTab = FindTabControlForId(m_tabSelection); - + if (hitControl == currentTab) - return FALSE; - + return false; + ChangeTab(hitControl); - - return TRUE; + + return true; } bool wxTabView::ChangeTab(wxTabControl *control) @@ -846,88 +924,88 @@ bool wxTabView::ChangeTab(wxTabControl *control) int oldTab = -1; if (currentTab) oldTab = currentTab->GetId(); - + if (control == currentTab) - return TRUE; - - if (m_layers.Number() == 0) - return FALSE; - + return true; + + if (m_layers.GetCount() == 0) + return false; + if (!OnTabPreActivate(control->GetId(), oldTab)) - return FALSE; + return false; // Move the tab to the bottom MoveSelectionTab(control); if (currentTab) - currentTab->SetSelected(FALSE); - - control->SetSelected(TRUE); + currentTab->SetSelected(false); + + control->SetSelected(true); m_tabSelection = control->GetId(); OnTabActivate(control->GetId(), oldTab); - + // Leave window refresh for the implementing window - return TRUE; + return true; } // Move the selected tab to the bottom layer, if necessary, // without calling app activation code bool wxTabView::MoveSelectionTab(wxTabControl *control) { - if (m_layers.Number() == 0) - return FALSE; - - wxTabLayer *firstLayer = (wxTabLayer *)m_layers.First()->Data(); - + if (m_layers.GetCount() == 0) + return false; + + wxTabLayer *firstLayer = (wxTabLayer *)m_layers.GetFirst()->GetData(); + // Find what column this tab is at, so we can swap with the one at the bottom. // If we're on the bottom layer, then no need to swap. if (!firstLayer->Member(control)) { // Do a swap int col = 0; - wxNode *thisNode = FindTabNodeAndColumn(control, &col); + wxList::compatibility_iterator thisNode = FindTabNodeAndColumn(control, &col); if (!thisNode) - return FALSE; - wxNode *otherNode = firstLayer->Nth(col); + return false; + wxList::compatibility_iterator otherNode = firstLayer->Item(col); if (!otherNode) - return FALSE; - + return false; + // If this is already in the bottom layer, return now if (otherNode == thisNode) - return TRUE; - - wxTabControl *otherTab = (wxTabControl *)otherNode->Data(); - + return true; + + wxTabControl *otherTab = (wxTabControl *)otherNode->GetData(); + // We now have pointers to the tab to be changed to, // and the tab on the first layer. Swap tab structures and // position details. - + int thisX = control->GetX(); int thisY = control->GetY(); int thisColPos = control->GetColPosition(); int otherX = otherTab->GetX(); int otherY = otherTab->GetY(); int otherColPos = otherTab->GetColPosition(); - + control->SetPosition(otherX, otherY); control->SetColPosition(otherColPos); otherTab->SetPosition(thisX, thisY); otherTab->SetColPosition(thisColPos); - + // Swap the data for the nodes thisNode->SetData(otherTab); otherNode->SetData(control); } - return TRUE; + return true; } // Called when a tab is activated void wxTabView::OnTabActivate(int /*activateId*/, int /*deactivateId*/) { } - + void wxTabView::SetHighlightColour(const wxColour& col) { m_highlightColour = col; @@ -947,45 +1025,61 @@ void wxTabView::SetBackgroundColour(const wxColour& col) m_backgroundBrush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID); } +// this may be called with sel = zero (which doesn't match any page) +// when wxMotif deletes a page +// so return the first tab... + void wxTabView::SetTabSelection(int sel, bool activateTool) { + if ( sel==m_tabSelection ) + return; + int oldSel = m_tabSelection; wxTabControl *control = FindTabControlForId(sel); + if (sel == 0) sel=control->GetId(); + wxTabControl *oldControl = FindTabControlForId(m_tabSelection); if (!OnTabPreActivate(sel, oldSel)) return; - + if (control) - control->SetSelected((sel != 0)); // TODO ?? - else + control->SetSelected((sel != -1)); // TODO ?? + else if (sel != -1) { - wxMessageBox(_("Could not find tab for id"), _("Error"), wxOK); + wxFAIL_MSG(_("Could not find tab for id")); return; } - + + if (oldControl) + oldControl->SetSelected(false); + m_tabSelection = sel; - MoveSelectionTab(control); - + + if (control) + MoveSelectionTab(control); + if (activateTool) OnTabActivate(sel, oldSel); } // Find tab control for id +// this may be called with zero (which doesn't match any page) +// so return the first control... wxTabControl *wxTabView::FindTabControlForId(int id) const { - wxNode *node1 = m_layers.First(); + wxTabLayerList::compatibility_iterator node1 = m_layers.GetFirst(); while (node1) { - wxTabLayer *layer = (wxTabLayer *)node1->Data(); - wxNode *node2 = layer->First(); + wxTabLayer *layer = (wxTabLayer *)node1->GetData(); + wxList::compatibility_iterator node2 = layer->GetFirst(); while (node2) { - wxTabControl *control = (wxTabControl *)node2->Data(); - if (control->GetId() == id) + wxTabControl *control = (wxTabControl *)node2->GetData(); + if (control->GetId() == id || id == 0) return control; - node2 = node2->Next(); + node2 = node2->GetNext(); } - node1 = node1->Next(); + node1 = node1->GetNext(); } return (wxTabControl *) NULL; } @@ -993,39 +1087,39 @@ wxTabControl *wxTabView::FindTabControlForId(int id) const // Find tab control for layer, position (starting from zero) wxTabControl *wxTabView::FindTabControlForPosition(int layer, int position) const { - wxNode *node1 = m_layers.Nth(layer); + wxTabLayerList::compatibility_iterator node1 = m_layers.Item(layer); if (!node1) return (wxTabControl *) NULL; - wxTabLayer *tabLayer = (wxTabLayer *)node1->Data(); - wxNode *node2 = tabLayer->Nth(position); + wxTabLayer *tabLayer = (wxTabLayer *)node1->GetData(); + wxList::compatibility_iterator node2 = tabLayer->Item(position); if (!node2) return (wxTabControl *) NULL; - return (wxTabControl *)node2->Data(); + return (wxTabControl *)node2->GetData(); } // Find the node and the column at which this control is positioned. -wxNode *wxTabView::FindTabNodeAndColumn(wxTabControl *control, int *col) const +wxList::compatibility_iterator wxTabView::FindTabNodeAndColumn(wxTabControl *control, int *col) const { - wxNode *node1 = m_layers.First(); + wxTabLayerList::compatibility_iterator node1 = m_layers.GetFirst(); while (node1) { - wxTabLayer *layer = (wxTabLayer *)node1->Data(); + wxTabLayer *layer = (wxTabLayer *)node1->GetData(); int c = 0; - wxNode *node2 = layer->First(); + wxList::compatibility_iterator node2 = layer->GetFirst(); while (node2) { - wxTabControl *cnt = (wxTabControl *)node2->Data(); + wxTabControl *cnt = (wxTabControl *)node2->GetData(); if (cnt == control) { *col = c; return node2; } - node2 = node2->Next(); + node2 = node2->GetNext(); c ++; } - node1 = node1->Next(); + node1 = node1->GetNext(); } - return (wxNode *) NULL; + return wxList::compatibility_iterator(); } int wxTabView::CalculateTabWidth(int noTabs, bool adjustView) @@ -1041,7 +1135,7 @@ int wxTabView::CalculateTabWidth(int noTabs, bool adjustView) /* * wxTabbedDialog */ - + IMPLEMENT_CLASS(wxTabbedDialog, wxDialog) BEGIN_EVENT_TABLE(wxTabbedDialog, wxDialog) @@ -1064,7 +1158,7 @@ wxTabbedDialog::~wxTabbedDialog(void) if (m_tabView) delete m_tabView; } - + void wxTabbedDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event) ) { Destroy(); @@ -1086,7 +1180,7 @@ void wxTabbedDialog::OnPaint(wxPaintEvent& WXUNUSED(event) ) /* * wxTabbedPanel */ - + IMPLEMENT_CLASS(wxTabbedPanel, wxPanel) BEGIN_EVENT_TABLE(wxTabbedPanel, wxPanel) @@ -1105,7 +1199,7 @@ wxTabbedPanel::~wxTabbedPanel(void) { delete m_tabView; } - + void wxTabbedPanel::OnMouseEvent(wxMouseEvent& event) { if (m_tabView) @@ -1122,10 +1216,11 @@ void wxTabbedPanel::OnPaint(wxPaintEvent& WXUNUSED(event) ) /* * wxPanelTabView */ - + IMPLEMENT_CLASS(wxPanelTabView, wxTabView) - -wxPanelTabView::wxPanelTabView(wxPanel *pan, long style): wxTabView(style), m_tabWindows(wxKEY_INTEGER) + +wxPanelTabView::wxPanelTabView(wxPanel *pan, long style) + : wxTabView(style) { m_panel = pan; m_currentWindow = (wxWindow *) NULL; @@ -1140,7 +1235,7 @@ wxPanelTabView::wxPanelTabView(wxPanel *pan, long style): wxTabView(style), m_ta wxPanelTabView::~wxPanelTabView(void) { - ClearWindows(TRUE); + ClearWindows(true); } // Called when a tab is activated @@ -1148,39 +1243,37 @@ void wxPanelTabView::OnTabActivate(int activateId, int deactivateId) { if (!m_panel) return; - + wxWindow *oldWindow = ((deactivateId == -1) ? 0 : GetTabWindow(deactivateId)); wxWindow *newWindow = GetTabWindow(activateId); if (oldWindow) - oldWindow->Show(FALSE); + oldWindow->Show(false); if (newWindow) - newWindow->Show(TRUE); - + newWindow->Show(true); + m_panel->Refresh(); } - + void wxPanelTabView::AddTabWindow(int id, wxWindow *window) { - m_tabWindows.Append((long)id, window); - window->Show(FALSE); + wxASSERT(m_tabWindows.find(id) == m_tabWindows.end()); + m_tabWindows[id] = window; + window->Show(false); } wxWindow *wxPanelTabView::GetTabWindow(int id) const { - wxNode *node = m_tabWindows.Find((long)id); - if (!node) - return (wxWindow *) NULL; - return (wxWindow *)node->Data(); + wxIntToWindowHashMap::const_iterator it = m_tabWindows.find(id); + return it == m_tabWindows.end() ? NULL : it->second; } void wxPanelTabView::ClearWindows(bool deleteWindows) { if (deleteWindows) - m_tabWindows.DeleteContents(TRUE); - m_tabWindows.Clear(); - m_tabWindows.DeleteContents(FALSE); + WX_CLEAR_HASH_MAP(wxIntToWindowHashMap, m_tabWindows); + m_tabWindows.clear(); } void wxPanelTabView::ShowWindowForTab(int id) @@ -1189,8 +1282,9 @@ void wxPanelTabView::ShowWindowForTab(int id) if (newWindow == m_currentWindow) return; if (m_currentWindow) - m_currentWindow->Show(FALSE); - newWindow->Show(TRUE); + m_currentWindow->Show(false); + newWindow->Show(true); newWindow->Refresh(); } +#endif // wxUSE_TAB_DIALOG