X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d61989a7de90c62c12ddd61cb820162897ed22cd..00b89a1d1da61a1f842db63b244ad08c0554121c:/src/aui/auibook.cpp diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 365339947c..0b7dfad98b 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -34,27 +34,29 @@ #include "wx/renderer.h" #ifdef __WXMAC__ -#include "wx/mac/carbon/private.h" +#include "wx/osx/private.h" #endif #include "wx/arrimpl.cpp" 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) -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_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) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN) +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_BUTTON, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_CANCEL_DRAG, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, wxAuiNotebookEvent); +wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, wxAuiNotebookEvent); IMPLEMENT_CLASS(wxAuiNotebook, wxControl) IMPLEMENT_CLASS(wxAuiTabCtrl, wxControl) @@ -67,8 +69,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxEvent) // these functions live in dockart.cpp -- they'll eventually // be moved to a new utility cpp file -wxColor wxAuiStepColour(const wxColor& c, int percent); - wxBitmap wxAuiBitmapFromBits(const unsigned char bits[], int w, int h, const wxColour& color); @@ -91,8 +91,8 @@ static void DrawButtons(wxDC& dc, if (button_state == wxAUI_BUTTON_STATE_HOVER || button_state == wxAUI_BUTTON_STATE_PRESSED) { - dc.SetBrush(wxBrush(wxAuiStepColour(bkcolour, 120))); - dc.SetPen(wxPen(wxAuiStepColour(bkcolour, 75))); + dc.SetBrush(wxBrush(bkcolour.ChangeLightness(120))); + dc.SetPen(wxPen(bkcolour.ChangeLightness(75))); // draw the background behind the button dc.DrawRectangle(rect.x, rect.y, 15, 15); @@ -144,33 +144,33 @@ private: // -- bitmaps -- #if defined( __WXMAC__ ) - static unsigned char close_bits[]={ + static const unsigned char close_bits[]={ 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3, 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3, 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF }; #elif defined( __WXGTK__) - static unsigned char close_bits[]={ + static const unsigned char close_bits[]={ 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8, 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef, 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; #else - static unsigned char close_bits[]={ + static const unsigned char close_bits[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9, 0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; #endif -static unsigned char left_bits[] = { +static const unsigned char left_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe, 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -static unsigned char right_bits[] = { +static const unsigned char right_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff, 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -static unsigned char list_bits[] = { +static const unsigned char list_bits[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -192,10 +192,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 @@ -206,11 +204,12 @@ wxAuiDefaultTabArt::wxAuiDefaultTabArt() (255-base_colour.Green()) + (255-base_colour.Blue()) < 60) { - base_colour = wxAuiStepColour(base_colour, 92); + base_colour = base_colour.ChangeLightness(92); } + m_active_colour = base_colour; m_base_colour = base_colour; - wxColor border_colour = wxAuiStepColour(base_colour, 75); + wxColor border_colour = base_colour.ChangeLightness(75); m_border_pen = wxPen(border_colour); m_base_colour_pen = wxPen(m_base_colour); @@ -237,12 +236,7 @@ wxAuiDefaultTabArt::~wxAuiDefaultTabArt() wxAuiTabArt* wxAuiDefaultTabArt::Clone() { - wxAuiDefaultTabArt* art = new wxAuiDefaultTabArt; - art->SetNormalFont(m_normal_font); - art->SetSelectedFont(m_selected_font); - art->SetMeasuringFont(m_measuring_font); - - return art; + return new wxAuiDefaultTabArt(*this); } void wxAuiDefaultTabArt::SetFlags(unsigned int flags) @@ -286,17 +280,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 = m_base_colour.ChangeLightness(90); + wxColor bottom_color = m_base_colour.ChangeLightness(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); + } } @@ -393,13 +409,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; @@ -411,8 +440,8 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc, // draw base background color wxRect r(tab_x, tab_y, tab_width, tab_height); - dc.SetPen(m_base_colour_pen); - dc.SetBrush(m_base_colour_brush); + dc.SetPen(wxPen(m_active_colour)); + dc.SetBrush(wxBrush(m_active_colour)); dc.DrawRectangle(r.x+1, r.y+1, r.width-1, r.height-4); // this white helps fill out the gradient at the top of the tab @@ -421,20 +450,20 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc, dc.DrawRectangle(r.x+2, r.y+1, r.width-3, r.height-4); // these two points help the rounded corners appear more antialiased - dc.SetPen(m_base_colour_pen); + dc.SetPen(wxPen(m_active_colour)); dc.DrawPoint(r.x+2, r.y+1); dc.DrawPoint(r.x+r.width-2, r.y+1); // set rectangle down a bit for gradient drawing r.SetHeight(r.GetHeight()/2); r.x += 2; - r.width -= 2; + r.width -= 3; r.y += r.height; r.y -= 2; // draw gradient background wxColor top_color = *wxWHITE; - wxColor bottom_color = m_base_colour; + wxColor bottom_color = m_active_colour; dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH); } else @@ -454,7 +483,7 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc, // -- draw top gradient fill for glossy look wxColor top_color = m_base_colour; - wxColor bottom_color = wxAuiStepColour(top_color, 160); + wxColor bottom_color = top_color.ChangeLightness(160); dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH); r.y += r.height; @@ -475,7 +504,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(m_base_colour.ChangeLightness(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, @@ -556,10 +590,15 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc, bmp = m_active_close_bmp; } + int offsetY = tab_y-1; + if (m_flags & wxAUI_NB_BOTTOM) + offsetY = 1; + wxRect rect(tab_x + tab_width - close_button_width - 1, - tab_y + (tab_height/2) - (bmp.GetHeight()/2), + offsetY + (tab_height/2) - (bmp.GetHeight()/2), close_button_width, tab_height); + IndentPressedBitmap(&rect, close_button_state); dc.DrawBitmap(bmp, rect.x, rect.y, true); @@ -689,7 +728,7 @@ void wxAuiDefaultTabArt::DrawButton(wxDC& dc, int wxAuiDefaultTabArt::ShowDropDown(wxWindow* wnd, const wxAuiNotebookPageArray& pages, - int active_idx) + int /*active_idx*/) { wxMenu menuPopup; @@ -704,12 +743,10 @@ int wxAuiDefaultTabArt::ShowDropDown(wxWindow* wnd, if (caption.IsEmpty()) caption = wxT(" "); - menuPopup.AppendCheckItem(1000+i, caption); - } - - if (active_idx != -1) - { - menuPopup.Check(1000+active_idx, true); + wxMenuItem* item = new wxMenuItem(NULL, 1000+i, caption); + if (page.bitmap.IsOk()) + item->SetBitmap(page.bitmap); + menuPopup.Append(item); } // find out where to put the popup menu of window items @@ -796,6 +833,18 @@ void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont& font) m_measuring_font = font; } +void wxAuiDefaultTabArt::SetColour(const wxColour& colour) +{ + m_base_colour = colour; + m_border_pen = wxPen(m_base_colour.ChangeLightness(75)); + m_base_colour_pen = wxPen(m_base_colour); + m_base_colour_brush = wxBrush(m_base_colour); +} + +void wxAuiDefaultTabArt::SetActiveColour(const wxColour& colour) +{ + m_active_colour = colour; +} // -- wxAuiSimpleTabArt class implementation -- @@ -841,10 +890,9 @@ wxAuiSimpleTabArt::~wxAuiSimpleTabArt() wxAuiTabArt* wxAuiSimpleTabArt::Clone() { - return static_cast(new wxAuiSimpleTabArt); + return new wxAuiSimpleTabArt(*this); } - void wxAuiSimpleTabArt::SetFlags(unsigned int flags) { m_flags = flags; @@ -878,6 +926,19 @@ void wxAuiSimpleTabArt::SetSizingInfo(const wxSize& tab_ctrl_size, m_fixed_tab_width = 220; } +void wxAuiSimpleTabArt::SetColour(const wxColour& colour) +{ + m_bkbrush = wxBrush(colour); + m_normal_bkbrush = wxBrush(colour); + m_normal_bkpen = wxPen(colour); +} + +void wxAuiSimpleTabArt::SetActiveColour(const wxColour& colour) +{ + m_selected_bkbrush = wxBrush(colour); + m_selected_bkpen = wxPen(colour); +} + void wxAuiSimpleTabArt::DrawBackground(wxDC& dc, wxWindow* WXUNUSED(wnd), const wxRect& rect) @@ -1330,6 +1391,16 @@ void wxAuiTabContainer::SetMeasuringFont(const wxFont& font) m_art->SetMeasuringFont(font); } +void wxAuiTabContainer::SetColour(const wxColour& colour) +{ + m_art->SetColour(colour); +} + +void wxAuiTabContainer::SetActiveColour(const wxColour& colour) +{ + m_art->SetActiveColour(colour); +} + void wxAuiTabContainer::SetRect(const wxRect& rect) { m_rect = rect; @@ -1572,6 +1643,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(); @@ -2009,7 +2085,7 @@ bool wxAuiTabContainer::TabHitTest(int x, int y, wxWindow** hit) const return false; wxAuiTabContainerButton* btn = NULL; - if (ButtonHitTest(x, y, &btn)) + if (ButtonHitTest(x, y, &btn) && !(btn->cur_state & wxAUI_BUTTON_STATE_DISABLED)) { if (m_buttons.Index(*btn) != wxNOT_FOUND) return false; @@ -2047,8 +2123,7 @@ bool wxAuiTabContainer::ButtonHitTest(int x, int y, { wxAuiTabContainerButton& button = m_buttons.Item(i); if (button.rect.Contains(x,y) && - !(button.cur_state & (wxAUI_BUTTON_STATE_HIDDEN | - wxAUI_BUTTON_STATE_DISABLED))) + !(button.cur_state & wxAUI_BUTTON_STATE_HIDDEN )) { if (hit) *hit = &button; @@ -2135,7 +2210,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) @@ -2147,6 +2222,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() @@ -2229,6 +2305,20 @@ void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt) } } +void wxAuiTabCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event)) +{ + if (m_is_dragging) + { + m_is_dragging = false; + + wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_CANCEL_DRAG, m_windowId); + evt.SetSelection(GetIdxFromWindow(m_click_tab)); + evt.SetOldSelection(evt.GetSelection()); + evt.SetEventObject(this); + GetEventHandler()->ProcessEvent(evt); + } +} + void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt) { if (GetCapture() == this) @@ -2251,7 +2341,8 @@ void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt) { // make sure we're still clicking the button wxAuiTabContainerButton* button = NULL; - if (!ButtonHitTest(evt.m_x, evt.m_y, &button)) + if (!ButtonHitTest(evt.m_x, evt.m_y, &button) || + button->cur_state & wxAUI_BUTTON_STATE_DISABLED) return; if (button != m_pressed_button) @@ -2328,13 +2419,25 @@ 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(); // check if the mouse is hovering above a button wxAuiTabContainerButton* button; - if (ButtonHitTest(pos.x, pos.y, &button)) + if (ButtonHitTest(pos.x, pos.y, &button) && !(button->cur_state & wxAUI_BUTTON_STATE_DISABLED)) { if (m_hover_button && button != m_hover_button) { @@ -2525,7 +2628,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) { @@ -2535,7 +2650,7 @@ void wxAuiTabCtrl::OnChar(wxKeyEvent& event) newPage = GetActivePage() + 1; } } - else if (key == WXK_LEFT) + else if (key == backwardKey) { if (m_pages.GetCount() > 1) { @@ -2620,9 +2735,25 @@ public: if (!m_tabs) return; + if (m_tabs->IsFrozen() || m_tabs->GetParent()->IsFrozen()) + 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(); @@ -2631,9 +2762,26 @@ 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))) @@ -2672,49 +2820,49 @@ const int wxAuiBaseTabCtrlId = 5380; // -- wxAuiNotebook class implementation -- +#define EVT_AUI_RANGE(id1, id2, event, func) \ + wx__DECLARE_EVT2(event, id1, id2, wxAuiNotebookEventHandler(func)) + BEGIN_EVENT_TABLE(wxAuiNotebook, wxControl) EVT_SIZE(wxAuiNotebook::OnSize) EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocusNotebook) - EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, wxAuiNotebook::OnTabClicked) - EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, wxAuiNotebook::OnTabBeginDrag) - EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, wxAuiNotebook::OnTabEndDrag) - EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + wxEVT_COMMAND_AUINOTEBOOK_CANCEL_DRAG, + wxAuiNotebook::OnTabCancelDrag) + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, wxAuiNotebook::OnTabDragMotion) - EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, wxEVT_COMMAND_AUINOTEBOOK_BUTTON, wxAuiNotebook::OnTabButton) - EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN, wxAuiNotebook::OnTabMiddleDown) - EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP, wxAuiNotebook::OnTabMiddleUp) - EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN, wxAuiNotebook::OnTabRightDown) - EVT_COMMAND_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, + EVT_AUI_RANGE(wxAuiBaseTabCtrlId, wxAuiBaseTabCtrlId+500, wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP, wxAuiNotebook::OnTabRightUp) + EVT_AUI_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) - -wxAuiNotebook::wxAuiNotebook() +void wxAuiNotebook::Init() { m_curpage = -1; m_tab_id_counter = wxAuiBaseTabCtrlId; @@ -2724,18 +2872,6 @@ wxAuiNotebook::wxAuiNotebook() m_requested_tabctrl_height = -1; } -wxAuiNotebook::wxAuiNotebook(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style) : wxControl(parent, id, pos, size, style) -{ - m_dummy_wnd = NULL; - m_requested_bmp_size = wxDefaultSize; - m_requested_tabctrl_height = -1; - InitNotebook(style); -} - bool wxAuiNotebook::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, @@ -2754,9 +2890,6 @@ bool wxAuiNotebook::Create(wxWindow* parent, // code called by all constructors void wxAuiNotebook::InitNotebook(long style) { - WX_INIT_CONTROL_CONTAINER(); - // SetCanFocus(false); - SetName(wxT("wxAuiNotebook")); m_curpage = -1; m_tab_id_counter = wxAuiBaseTabCtrlId; @@ -2786,6 +2919,9 @@ void wxAuiNotebook::InitNotebook(long style) wxAuiNotebook::~wxAuiNotebook() { + // Indicate we're deleting pages + SendDestroyEvent(); + while ( GetPageCount() > 0 ) DeletePage(0); @@ -2796,7 +2932,23 @@ void wxAuiNotebook::SetArtProvider(wxAuiTabArt* art) { m_tabs.SetArtProvider(art); - UpdateTabCtrlHeight(); + // Update the height and do nothing else if it did something but otherwise + // (i.e. if the new art provider uses the same height as the old one) we + // need to manually set the art provider for all tabs ourselves. + if ( !UpdateTabCtrlHeight() ) + { + wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes(); + const size_t pane_count = all_panes.GetCount(); + for (size_t i = 0; i < pane_count; ++i) + { + wxAuiPaneInfo& pane = all_panes.Item(i); + if (pane.name == wxT("dummy")) + continue; + wxTabFrame* tab_frame = (wxTabFrame*)pane.window; + wxAuiTabCtrl* tabctrl = tab_frame->m_tabs; + tabctrl->SetArtProvider(art->Clone()); + } + } } // SetTabCtrlHeight() is the highest-level override of the @@ -2804,7 +2956,7 @@ void wxAuiNotebook::SetArtProvider(wxAuiTabArt* art) // specified tab ctrl height, overriding all other considerations, // such as text or bitmap height. It overrides any call to // SetUniformBitmapSize(). Specifying a height of -1 reverts -// any previous call and returns to the default behavior +// any previous call and returns to the default behaviour void wxAuiNotebook::SetTabCtrlHeight(int height) { @@ -2837,34 +2989,36 @@ void wxAuiNotebook::SetUniformBitmapSize(const wxSize& size) } // UpdateTabCtrlHeight() does the actual tab resizing. It's meant -// to be used interally -void wxAuiNotebook::UpdateTabCtrlHeight() +// to be used internally +bool wxAuiNotebook::UpdateTabCtrlHeight() { // get the tab ctrl height we will use int height = CalculateTabCtrlHeight(); // if the tab control height needs to change, update // all of our tab controls with the new height - if (m_tab_ctrl_height != height) - { - wxAuiTabArt* art = m_tabs.GetArtProvider(); + if (m_tab_ctrl_height == height) + return false; - m_tab_ctrl_height = height; + wxAuiTabArt* art = m_tabs.GetArtProvider(); - wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes(); - size_t i, pane_count = all_panes.GetCount(); - for (i = 0; i < pane_count; ++i) - { - wxAuiPaneInfo& pane = all_panes.Item(i); - if (pane.name == wxT("dummy")) - continue; - wxTabFrame* tab_frame = (wxTabFrame*)pane.window; - wxAuiTabCtrl* tabctrl = tab_frame->m_tabs; - tab_frame->SetTabCtrlHeight(m_tab_ctrl_height); - tabctrl->SetArtProvider(art->Clone()); - tab_frame->DoSizing(); - } + m_tab_ctrl_height = height; + + wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes(); + size_t i, pane_count = all_panes.GetCount(); + for (i = 0; i < pane_count; ++i) + { + wxAuiPaneInfo& pane = all_panes.Item(i); + if (pane.name == wxT("dummy")) + continue; + wxTabFrame* tab_frame = (wxTabFrame*)pane.window; + wxAuiTabCtrl* tabctrl = tab_frame->m_tabs; + tab_frame->SetTabCtrlHeight(m_tab_ctrl_height); + tabctrl->SetArtProvider(art->Clone()); + tab_frame->DoSizing(); } + + return true; } void wxAuiNotebook::UpdateHintWindowSize() @@ -2982,6 +3136,10 @@ 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; @@ -3145,12 +3303,11 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) RemoveEmptyTabFrames(); - // set new active pane - if (new_active) - { - m_curpage = -1; + m_curpage = wxNOT_FOUND; + + // set new active pane unless we're being destroyed anyhow + if (new_active && !m_isBeingDeleted) SetSelectionToWindow(new_active); - } return true; } @@ -3320,7 +3477,22 @@ size_t wxAuiNotebook::SetSelection(size_t new_page) void wxAuiNotebook::SetSelectionToWindow(wxWindow *win) { const int idx = m_tabs.GetIdxFromWindow(win); - wxCHECK_RET( idx != wxNOT_FOUND, _T("invalid notebook page") ); + wxCHECK_RET( idx != wxNOT_FOUND, wxT("invalid notebook page") ); + + + // since a tab was clicked, let the parent know that we received + // the focus, even if we will assign that focus immediately + // to the child tab in the SetSelection call below + // (the child focus event will also let wxAuiManager, if any, + // know that the notebook control has been activated) + + wxWindow* parent = GetParent(); + if (parent) + { + wxChildFocusEvent eventFocus(this); + parent->GetEventHandler()->ProcessEvent(eventFocus); + } + SetSelection(idx); } @@ -3550,10 +3722,8 @@ void wxAuiNotebook::OnSize(wxSizeEvent& evt) evt.Skip(); } -void wxAuiNotebook::OnTabClicked(wxCommandEvent& command_evt) +void wxAuiNotebook::OnTabClicked(wxAuiNotebookEvent& evt) { - wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt; - wxAuiTabCtrl* ctrl = (wxAuiTabCtrl*)evt.GetEventObject(); wxASSERT(ctrl != NULL); @@ -3563,12 +3733,20 @@ void wxAuiNotebook::OnTabClicked(wxCommandEvent& command_evt) SetSelectionToWindow(wnd); } -void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent&) +void wxAuiNotebook::OnTabBgDClick(wxAuiNotebookEvent& 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(wxAuiNotebookEvent&) { m_last_drag_x = 0; } -void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt) +void wxAuiNotebook::OnTabDragMotion(wxAuiNotebookEvent& evt) { wxPoint screen_pt = ::wxGetMousePosition(); wxPoint client_pt = ScreenToClient(screen_pt); @@ -3699,15 +3877,13 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt) -void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt) +void wxAuiNotebook::OnTabEndDrag(wxAuiNotebookEvent& evt) { - wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt; - m_mgr.HideHint(); wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject(); - wxCHECK_RET( src_tabs, _T("no source object?") ); + wxCHECK_RET( src_tabs, wxT("no source object?") ); src_tabs->SetCursor(wxCursor(wxCURSOR_ARROW)); @@ -3770,7 +3946,7 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt) // get main index of the page int main_idx = m_tabs.GetIdxFromWindow(src_page); - wxCHECK_RET( main_idx != wxNOT_FOUND, _T("no source page?") ); + wxCHECK_RET( main_idx != wxNOT_FOUND, wxT("no source page?") ); // make a copy of the page info @@ -3928,6 +4104,18 @@ void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt) +void wxAuiNotebook::OnTabCancelDrag(wxAuiNotebookEvent& command_evt) +{ + wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt; + + m_mgr.HideHint(); + + wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject(); + wxCHECK_RET( src_tabs, _T("no source object?") ); + + src_tabs->SetCursor(wxCursor(wxCURSOR_ARROW)); +} + wxAuiTabCtrl* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint& pt) { // if we've just removed the last tab from the source @@ -4017,11 +4205,14 @@ void wxAuiNotebook::RemoveEmptyTabFrames() m_mgr.GetPane(first_good).Centre(); } - m_mgr.Update(); + if (!m_isBeingDeleted) + m_mgr.Update(); } void wxAuiNotebook::OnChildFocusNotebook(wxChildFocusEvent& evt) { + evt.Skip(); + // 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 // was hidden. In the bug, the focus would return to the notebook @@ -4125,9 +4316,8 @@ void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent& event) } } -void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt) +void wxAuiNotebook::OnTabButton(wxAuiNotebookEvent& evt) { - wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt; wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject(); int button_id = evt.GetInt(); @@ -4140,7 +4330,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) @@ -4168,7 +4358,7 @@ void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt) #endif { int main_idx = m_tabs.GetIdxFromWindow(close_wnd); - wxCHECK_RET( main_idx != wxNOT_FOUND, _T("no page to delete?") ); + wxCHECK_RET( main_idx != wxNOT_FOUND, wxT("no page to delete?") ); DeletePage(main_idx); } @@ -4183,7 +4373,7 @@ void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt) } -void wxAuiNotebook::OnTabMiddleDown(wxCommandEvent& evt) +void wxAuiNotebook::OnTabMiddleDown(wxAuiNotebookEvent& evt) { // patch event through to owner wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject(); @@ -4195,7 +4385,7 @@ void wxAuiNotebook::OnTabMiddleDown(wxCommandEvent& evt) GetEventHandler()->ProcessEvent(e); } -void wxAuiNotebook::OnTabMiddleUp(wxCommandEvent& evt) +void wxAuiNotebook::OnTabMiddleUp(wxAuiNotebookEvent& evt) { // if the wxAUI_NB_MIDDLE_CLICK_CLOSE is specified, middle // click should act like a tab close action. However, first @@ -4222,7 +4412,7 @@ void wxAuiNotebook::OnTabMiddleUp(wxCommandEvent& evt) OnTabButton(evt); } -void wxAuiNotebook::OnTabRightDown(wxCommandEvent& evt) +void wxAuiNotebook::OnTabRightDown(wxAuiNotebookEvent& evt) { // patch event through to owner wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject(); @@ -4234,7 +4424,7 @@ void wxAuiNotebook::OnTabRightDown(wxCommandEvent& evt) GetEventHandler()->ProcessEvent(e); } -void wxAuiNotebook::OnTabRightUp(wxCommandEvent& evt) +void wxAuiNotebook::OnTabRightUp(wxAuiNotebookEvent& evt) { // patch event through to owner wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject(); @@ -4347,4 +4537,11 @@ bool wxAuiNotebook::ShowWindowMenu() return false; } +void wxAuiNotebook::Thaw() +{ + DoSizing(); + + wxControl::Thaw(); +} + #endif // wxUSE_AUI