X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c7bfb76a2cf367dcdbff8f9a97e3250053a1adca..17dd542b4962d401823b655df0e7b46e710a4c54:/src/aui/auibook.cpp diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 6288695abe..dc5ce84949 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -34,7 +34,9 @@ #include "wx/renderer.h" #ifdef __WXMAC__ -#include "wx/mac/carbon/private.h" +#include "wx/osx/private.h" +// for themeing support +#include #endif #include "wx/arrimpl.cpp" @@ -42,6 +44,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 +52,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) @@ -190,10 +195,8 @@ wxAuiDefaultTabArt::wxAuiDefaultTabArt() m_fixed_tab_width = 100; m_tab_ctrl_height = 0; -#ifdef __WXMAC__ - wxBrush toolbarbrush; - toolbarbrush.MacSetTheme( kThemeBrushToolbarBackground ); - wxColor base_colour = toolbarbrush.GetColour(); +#if defined( __WXMAC__ ) && wxOSX_USE_COCOA_OR_CARBON + wxColor base_colour = wxColour( wxMacCreateCGColorFromHITheme(kThemeBrushToolbarBackground)); #else wxColor base_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); #endif @@ -284,17 +287,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 +416,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 +511,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, @@ -1570,6 +1613,11 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) return; wxMemoryDC dc; + + // use the same layout direction as the window DC uses to ensure that the + // text is rendered correctly + dc.SetLayoutDirection(raw_dc->GetLayoutDirection()); + wxBitmap bmp; size_t i; size_t page_count = m_pages.GetCount(); @@ -1946,22 +1994,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 +2126,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 +2181,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) @@ -2159,6 +2193,7 @@ BEGIN_EVENT_TABLE(wxAuiTabCtrl, wxControl) EVT_SET_FOCUS(wxAuiTabCtrl::OnSetFocus) EVT_KILL_FOCUS(wxAuiTabCtrl::OnKillFocus) EVT_CHAR(wxAuiTabCtrl::OnChar) + EVT_MOUSE_CAPTURE_LOST(wxAuiTabCtrl::OnCaptureLost) END_EVENT_TABLE() @@ -2241,6 +2276,10 @@ void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt) } } +void wxAuiTabCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event)) +{ +} + void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt) { if (GetCapture() == this) @@ -2340,6 +2379,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(); @@ -2537,7 +2588,19 @@ void wxAuiTabCtrl::OnChar(wxKeyEvent& event) int newPage = -1; - if (key == WXK_RIGHT) + int forwardKey, backwardKey; + if (GetLayoutDirection() == wxLayout_RightToLeft) + { + forwardKey = WXK_LEFT; + backwardKey = WXK_RIGHT; + } + else + { + forwardKey = WXK_RIGHT; + backwardKey = WXK_LEFT; + } + + if (key == forwardKey) { if (m_pages.GetCount() > 1) { @@ -2547,7 +2610,7 @@ void wxAuiTabCtrl::OnChar(wxKeyEvent& event) newPage = GetActivePage() + 1; } } - else if (key == WXK_LEFT) + else if (key == backwardKey) { if (m_pages.GetCount() > 1) { @@ -2633,8 +2696,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(); @@ -2643,15 +2719,34 @@ public: for (i = 0; i < page_count; ++i) { + int height = m_rect.height - m_tab_ctrl_height; + if ( height < 0 ) + { + // avoid passing negative height to wxWindow::SetSize(), this + // results in assert failures/GTK+ warnings + height = 0; + } + 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, height); + } + else //TODO: if (GetFlags() & wxAUI_NB_TOP) + { + page.window->SetSize(m_rect.x, m_rect.y + m_tab_ctrl_height, + m_rect.width, 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 +2779,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 +2807,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 +2894,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 +3093,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 +3129,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 +3158,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 +3168,7 @@ bool wxAuiNotebook::DeletePage(size_t page_idx) wxPendingDelete.Append(wnd); } else +#endif { wnd->Destroy(); } @@ -3140,7 +3261,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 +3678,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 +3932,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 +4040,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 +4140,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 +4174,7 @@ void wxAuiNotebook::OnChildFocus(wxChildFocusEvent& evt) } } -void wxAuiNotebook::OnNavigationKey(wxNavigationKeyEvent& event) +void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent& event) { if ( event.IsWindowChange() ) { // change pages @@ -4120,7 +4264,7 @@ void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt) { // if the close button is to the right, use the active // page selection to determine which page to close - selection = GetSelection(); + selection = tabs->GetActivePage(); } if (selection != -1) @@ -4130,6 +4274,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 +4283,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); } } }