]> git.saurik.com Git - wxWidgets.git/blobdiff - src/aui/auibook.cpp
check that the version of __sync_sub_and_fetch that returns a value is supported...
[wxWidgets.git] / src / aui / auibook.cpp
index 6288695abe3705896bc8769fa576974e232fd9c2..048229f35fb6d3400a0c5f7f005b552e85316527 100644 (file)
@@ -42,6 +42,7 @@ WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray)
 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray)
 
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON)
@@ -49,6 +50,8 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN)
 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP)
@@ -191,9 +194,7 @@ wxAuiDefaultTabArt::wxAuiDefaultTabArt()
     m_tab_ctrl_height = 0;
 
 #ifdef __WXMAC__
-    wxBrush toolbarbrush;
-    toolbarbrush.MacSetTheme( kThemeBrushToolbarBackground );
-    wxColor base_colour = toolbarbrush.GetColour();
+    wxColor base_colour = wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground));
 #else
     wxColor base_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
 #endif
@@ -284,17 +285,39 @@ void wxAuiDefaultTabArt::DrawBackground(wxDC& dc,
                                         const wxRect& rect)
 {
     // draw background
-    wxRect r(rect.x, rect.y, rect.width+2, rect.height-3);
-    wxColor top_color = wxAuiStepColour(m_base_colour, 90);
-    wxColor bottom_color = wxAuiStepColour(m_base_colour, 170);
+
+    wxColor top_color       = wxAuiStepColour(m_base_colour, 90);
+    wxColor bottom_color   = wxAuiStepColour(m_base_colour, 170);
+    wxRect r;
+
+   if (m_flags &wxAUI_NB_BOTTOM)
+       r = wxRect(rect.x, rect.y, rect.width+2, rect.height);
+   // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
+   // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
+   else //for wxAUI_NB_TOP
+       r = wxRect(rect.x, rect.y, rect.width+2, rect.height-3);
+
     dc.GradientFillLinear(r, top_color, bottom_color, wxSOUTH);
 
-    // draw base lines
-    int y = rect.GetHeight();
-    int w = rect.GetWidth();
-    dc.SetPen(m_border_pen);
-    dc.SetBrush(m_base_colour_brush);
-    dc.DrawRectangle(-1, y-4, w+2, 4);
+
+   // draw base lines
+
+   dc.SetPen(m_border_pen);
+   int y = rect.GetHeight();
+   int w = rect.GetWidth();
+
+   if (m_flags &wxAUI_NB_BOTTOM)
+   {
+       dc.SetBrush(wxBrush(bottom_color));
+       dc.DrawRectangle(-1, 0, w+2, 4);
+   }
+   // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
+   // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
+   else //for wxAUI_NB_TOP
+   {
+       dc.SetBrush(m_base_colour_brush);
+       dc.DrawRectangle(-1, y-4, w+2, 4);
+   }
 }
 
 
@@ -391,13 +414,26 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
 
 
     wxPoint border_points[6];
-    border_points[0] = wxPoint(tab_x,             tab_y+tab_height-4);
-    border_points[1] = wxPoint(tab_x,             tab_y+2);
-    border_points[2] = wxPoint(tab_x+2,           tab_y);
-    border_points[3] = wxPoint(tab_x+tab_width-2, tab_y);
-    border_points[4] = wxPoint(tab_x+tab_width,   tab_y+2);
-    border_points[5] = wxPoint(tab_x+tab_width,   tab_y+tab_height-4);
-
+    if (m_flags &wxAUI_NB_BOTTOM)
+    {
+        border_points[0] = wxPoint(tab_x,             tab_y);
+        border_points[1] = wxPoint(tab_x,             tab_y+tab_height-6);
+        border_points[2] = wxPoint(tab_x+2,           tab_y+tab_height-4);
+        border_points[3] = wxPoint(tab_x+tab_width-2, tab_y+tab_height-4);
+        border_points[4] = wxPoint(tab_x+tab_width,   tab_y+tab_height-6);
+        border_points[5] = wxPoint(tab_x+tab_width,   tab_y);
+    }
+    else //if (m_flags & wxAUI_NB_TOP) {}
+    {
+        border_points[0] = wxPoint(tab_x,             tab_y+tab_height-4);
+        border_points[1] = wxPoint(tab_x,             tab_y+2);
+        border_points[2] = wxPoint(tab_x+2,           tab_y);
+        border_points[3] = wxPoint(tab_x+tab_width-2, tab_y);
+        border_points[4] = wxPoint(tab_x+tab_width,   tab_y+2);
+        border_points[5] = wxPoint(tab_x+tab_width,   tab_y+tab_height-4);
+    }
+    // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
+    // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
 
     int drawn_tab_yoff = border_points[1].y;
     int drawn_tab_height = border_points[0].y - border_points[1].y;
@@ -473,7 +509,12 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc,
     // this gets rid of the top one of those lines in the tab control
     if (page.active)
     {
-        dc.SetPen(m_base_colour_pen);
+        if (m_flags &wxAUI_NB_BOTTOM)
+            dc.SetPen(wxPen(wxColour(wxAuiStepColour(m_base_colour, 170))));
+        // TODO: else if (m_flags &wxAUI_NB_LEFT) {}
+        // TODO: else if (m_flags &wxAUI_NB_RIGHT) {}
+        else //for wxAUI_NB_TOP
+            dc.SetPen(m_base_colour_pen);
         dc.DrawLine(border_points[0].x+1,
                     border_points[0].y,
                     border_points[5].x,
@@ -1946,22 +1987,6 @@ bool wxAuiTabContainer::IsTabVisible(int tabPage, int tabOffset, wxDC* dc, wxWin
         wxAuiNotebookPage& page = m_pages.Item(i);
         wxAuiTabContainerButton& tab_button = m_tab_close_buttons.Item(i);
 
-        // determine if a close button is on this tab
-        if ((m_flags & wxAUI_NB_CLOSE_ON_ALL_TABS) != 0 ||
-            ((m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) != 0 && page.active))
-        {
-            if (tab_button.cur_state == wxAUI_BUTTON_STATE_HIDDEN)
-            {
-                tab_button.id = wxAUI_BUTTON_CLOSE;
-                tab_button.cur_state = wxAUI_BUTTON_STATE_NORMAL;
-                tab_button.location = wxCENTER;
-            }
-        }
-        else
-        {
-            tab_button.cur_state = wxAUI_BUTTON_STATE_HIDDEN;
-        }
-
         rect.x = offset;
         rect.width = m_rect.width - right_buttons_width - offset - 2;
 
@@ -2094,12 +2119,14 @@ bool wxAuiTabContainer::ButtonHitTest(int x, int y,
 // as the Show() method on this class is "unplugged"
 static void ShowWnd(wxWindow* wnd, bool show)
 {
+#if wxUSE_MDI
     if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
     {
         wxAuiMDIChildFrame* cf = (wxAuiMDIChildFrame*)wnd;
         cf->DoShow(show);
     }
     else
+#endif
     {
         wnd->Show(show);
     }
@@ -2147,7 +2174,7 @@ BEGIN_EVENT_TABLE(wxAuiTabCtrl, wxControl)
     EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground)
     EVT_SIZE(wxAuiTabCtrl::OnSize)
     EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown)
-    EVT_LEFT_DCLICK(wxAuiTabCtrl::OnLeftDown)
+    EVT_LEFT_DCLICK(wxAuiTabCtrl::OnLeftDClick)
     EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp)
     EVT_MIDDLE_DOWN(wxAuiTabCtrl::OnMiddleDown)
     EVT_MIDDLE_UP(wxAuiTabCtrl::OnMiddleUp)
@@ -2340,6 +2367,18 @@ void wxAuiTabCtrl::OnRightDown(wxMouseEvent& evt)
     GetEventHandler()->ProcessEvent(e);
 }
 
+void wxAuiTabCtrl::OnLeftDClick(wxMouseEvent& evt)
+{
+    wxWindow* wnd;
+    wxAuiTabContainerButton* button;
+    if (!TabHitTest(evt.m_x, evt.m_y, &wnd) && !ButtonHitTest(evt.m_x, evt.m_y, &button))
+    {
+        wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, m_windowId);
+        e.SetEventObject(this);
+        GetEventHandler()->ProcessEvent(e);
+    }
+}
+
 void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt)
 {
     wxPoint pos = evt.GetPosition();
@@ -2633,8 +2672,21 @@ public:
             return;
 
         m_tab_rect = wxRect(m_rect.x, m_rect.y, m_rect.width, m_tab_ctrl_height);
-        m_tabs->SetSize(m_rect.x, m_rect.y, m_rect.width, m_tab_ctrl_height);
-        m_tabs->SetRect(wxRect(0, 0, m_rect.width, m_tab_ctrl_height));
+        if (m_tabs->GetFlags() & wxAUI_NB_BOTTOM)
+        {
+            m_tab_rect = wxRect (m_rect.x, m_rect.y + m_rect.height - m_tab_ctrl_height, m_rect.width, m_tab_ctrl_height);
+            m_tabs->SetSize     (m_rect.x, m_rect.y + m_rect.height - m_tab_ctrl_height, m_rect.width, m_tab_ctrl_height);
+            m_tabs->SetRect     (wxRect(0, 0, m_rect.width, m_tab_ctrl_height));
+        }
+        else //TODO: if (GetFlags() & wxAUI_NB_TOP)
+        {
+            m_tab_rect = wxRect (m_rect.x, m_rect.y, m_rect.width, m_tab_ctrl_height);
+            m_tabs->SetSize     (m_rect.x, m_rect.y, m_rect.width, m_tab_ctrl_height);
+            m_tabs->SetRect     (wxRect(0, 0,        m_rect.width, m_tab_ctrl_height));
+        }
+        // TODO: else if (GetFlags() & wxAUI_NB_LEFT){}
+        // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){}
+
         m_tabs->Refresh();
         m_tabs->Update();
 
@@ -2644,14 +2696,26 @@ public:
         for (i = 0; i < page_count; ++i)
         {
             wxAuiNotebookPage& page = pages.Item(i);
-            page.window->SetSize(m_rect.x, m_rect.y + m_tab_ctrl_height,
-                                 m_rect.width, m_rect.height - m_tab_ctrl_height);
+            if (m_tabs->GetFlags() & wxAUI_NB_BOTTOM)
+            {
+                page.window->SetSize(m_rect.x, m_rect.y,
+                                     m_rect.width, m_rect.height - m_tab_ctrl_height);
+            }
+            else //TODO: if (GetFlags() & wxAUI_NB_TOP)
+            {
+                page.window->SetSize(m_rect.x, m_rect.y + m_tab_ctrl_height,
+                                  m_rect.width, m_rect.height - m_tab_ctrl_height);
+            }
+            // TODO: else if (GetFlags() & wxAUI_NB_LEFT){}
+            // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){}
 
+#if wxUSE_MDI
             if (page.window->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
             {
                 wxAuiMDIChildFrame* wnd = (wxAuiMDIChildFrame*)page.window;
                 wnd->ApplyMDIChildFrameRect();
             }
+#endif
         }
     }
 
@@ -2684,7 +2748,7 @@ const int wxAuiBaseTabCtrlId = 5380;
 
 BEGIN_EVENT_TABLE(wxAuiNotebook, wxControl)
     EVT_SIZE(wxAuiNotebook::OnSize)
-    EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocus)
+    EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocusNotebook)
     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
                       wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING,
                       wxAuiNotebook::OnTabClicked)
@@ -2712,9 +2776,17 @@ BEGIN_EVENT_TABLE(wxAuiNotebook, wxControl)
     EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
                       wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP,
                       wxAuiNotebook::OnTabRightUp)
-    EVT_NAVIGATION_KEY(wxAuiNotebook::OnNavigationKey)
+    EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500,
+                      wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK,
+                      wxAuiNotebook::OnTabBgDClick)
+    EVT_NAVIGATION_KEY(wxAuiNotebook::OnNavigationKeyNotebook)
 
+#ifdef wxHAS_NATIVE_TAB_TRAVERSAL
     WX_EVENT_TABLE_CONTROL_CONTAINER(wxAuiNotebook)
+#else
+    // Avoid clash with container event handler functions
+    EVT_SET_FOCUS(wxAuiNotebook::OnFocus)
+#endif
 END_EVENT_TABLE()
 
 WX_DELEGATE_TO_CONTROL_CONTAINER(wxAuiNotebook, wxControl)
@@ -2791,6 +2863,12 @@ void wxAuiNotebook::InitNotebook(long style)
 
 wxAuiNotebook::~wxAuiNotebook()
 {
+    // Indicate we're deleting pages
+    m_isBeingDeleted = true;
+
+    while ( GetPageCount() > 0 )
+        DeletePage(0);
+
     m_mgr.UnInit();
 }
 
@@ -2984,6 +3062,12 @@ bool wxAuiNotebook::InsertPage(size_t page_idx,
                                bool select,
                                const wxBitmap& bitmap)
 {
+    wxASSERT_MSG(page, wxT("page pointer must be non-NULL"));
+    if (!page)
+        return false;
+    
+    page->Reparent(this);
+
     wxAuiNotebookPage info;
     info.window = page;
     info.caption = caption;
@@ -3014,6 +3098,10 @@ bool wxAuiNotebook::InsertPage(size_t page_idx,
     DoSizing();
     active_tabctrl->DoShowHide();
 
+    // adjust selected index
+    if(m_curpage >= (int) page_idx)
+        m_curpage++;
+
     if (select)
     {
         SetSelectionToWindow(page);
@@ -3039,6 +3127,7 @@ bool wxAuiNotebook::DeletePage(size_t page_idx)
     if (!RemovePage(page_idx))
         return false;
 
+#if wxUSE_MDI
     // actually destroy the window now
     if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
     {
@@ -3048,6 +3137,7 @@ bool wxAuiNotebook::DeletePage(size_t page_idx)
             wxPendingDelete.Append(wnd);
     }
     else
+#endif
     {
         wnd->Destroy();
     }
@@ -3140,7 +3230,7 @@ bool wxAuiNotebook::RemovePage(size_t page_idx)
     RemoveEmptyTabFrames();
 
     // set new active pane
-    if (new_active)
+    if (new_active && !m_isBeingDeleted)
     {
         m_curpage = -1;
         SetSelectionToWindow(new_active);
@@ -3557,6 +3647,14 @@ void wxAuiNotebook::OnTabClicked(wxCommandEvent& command_evt)
     SetSelectionToWindow(wnd);
 }
 
+void wxAuiNotebook::OnTabBgDClick(wxCommandEvent& WXUNUSED(evt))
+{
+    // notify owner that the tabbar background has been double-clicked
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, m_windowId);
+    e.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(e);
+}
+
 void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent&)
 {
     m_last_drag_x = 0;
@@ -3803,6 +3901,13 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
                 // set the selection in the destination tab control
                 nb->SetSelectionToPage(page_info);
 
+                // notify owner that the tab has been dragged
+                wxAuiNotebookEvent e2(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, m_windowId);
+                e2.SetSelection(evt.GetSelection());
+                e2.SetOldSelection(evt.GetSelection());
+                e2.SetEventObject(this);
+                GetEventHandler()->ProcessEvent(e2);
+
                 return;
             }
         }
@@ -3904,6 +4009,13 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
 
         UpdateHintWindowSize();
     }
+
+    // notify owner that the tab has been dragged
+    wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, m_windowId);
+    e.SetSelection(evt.GetSelection());
+    e.SetOldSelection(evt.GetSelection());
+    e.SetEventObject(this);
+    GetEventHandler()->ProcessEvent(e);
 }
 
 
@@ -3997,10 +4109,11 @@ void wxAuiNotebook::RemoveEmptyTabFrames()
         m_mgr.GetPane(first_good).Centre();
     }
 
-    m_mgr.Update();
+    if (!m_isBeingDeleted)
+        m_mgr.Update();
 }
 
-void wxAuiNotebook::OnChildFocus(wxChildFocusEvent& evt)
+void wxAuiNotebook::OnChildFocusNotebook(wxChildFocusEvent& evt)
 {
     // if we're dragging a tab, don't change the current selection.
     // This code prevents a bug that used to happen when the hint window
@@ -4030,7 +4143,7 @@ void wxAuiNotebook::OnChildFocus(wxChildFocusEvent& evt)
     }
 }
 
-void wxAuiNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
+void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent& event)
 {
     if ( event.IsWindowChange() ) {
         // change pages
@@ -4130,6 +4243,8 @@ void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt)
             // ask owner if it's ok to close the tab
             wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, m_windowId);
             e.SetSelection(m_tabs.GetIdxFromWindow(close_wnd));
+            const int idx = m_tabs.GetIdxFromWindow(close_wnd);
+            e.SetSelection(idx);
             e.SetOldSelection(evt.GetSelection());
             e.SetEventObject(this);
             GetEventHandler()->ProcessEvent(e);
@@ -4137,17 +4252,25 @@ void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt)
                 return;
 
 
+#if wxUSE_MDI
             if (close_wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
             {
                 close_wnd->Close();
             }
             else
+#endif
             {
                 int main_idx = m_tabs.GetIdxFromWindow(close_wnd);
                 wxCHECK_RET( main_idx != wxNOT_FOUND, _T("no page to delete?") );
 
                 DeletePage(main_idx);
             }
+
+            // notify owner that the tab has been closed
+            wxAuiNotebookEvent e2(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, m_windowId);
+            e2.SetSelection(idx);
+            e2.SetEventObject(this);
+            GetEventHandler()->ProcessEvent(e2);
         }
     }
 }