X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/760d3542ec63db3a0eb4cc398520640203b8d6b0..e83a2e04900ec19e809d32d985669e1c664dd5a8:/src/aui/auibook.cpp diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index d97bd4daae..84ed97b2b2 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -31,6 +31,10 @@ #include "wx/dcbuffer.h" #include "wx/menu.h" +#ifdef __WXMAC__ +#include "wx/mac/carbon/private.h" +#endif + #include "wx/arrimpl.cpp" WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray) WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray) @@ -179,6 +183,11 @@ private: 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[]={ + 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[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9, @@ -216,19 +225,22 @@ wxAuiDefaultTabArt::wxAuiDefaultTabArt() m_measuring_font = m_selected_font; m_fixed_tab_width = 100; + m_tab_ctrl_height = 0; - wxColour base_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); - - wxColour background_colour = base_colour; - wxColour normaltab_colour = base_colour; - wxColour selectedtab_colour = base_colour; +#ifdef __WXMAC__ + wxBrush toolbarbrush; + toolbarbrush.MacSetTheme( kThemeBrushToolbarBackground ); + wxColor base_colour = toolbarbrush.GetColour(); +#else + wxColor base_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE); +#endif - m_bkbrush = wxBrush(background_colour); - m_normal_bkbrush = wxBrush(normaltab_colour); - m_normal_bkpen = wxPen(normaltab_colour); - m_selected_bkbrush = wxBrush(selectedtab_colour); - m_selected_bkpen = wxPen(selectedtab_colour); + m_base_colour = base_colour; + wxColor darker2_colour = StepColour(base_colour, 70); + m_border_pen = wxPen(darker2_colour); + m_base_colour_pen = wxPen(m_base_colour); + m_base_colour_brush = wxBrush(m_base_colour); m_active_close_bmp = BitmapFromBits(close_bits, 16, 16, *wxBLACK); m_disabled_close_bmp = BitmapFromBits(close_bits, 16, 16, wxColour(128,128,128)); @@ -279,6 +291,8 @@ void wxAuiDefaultTabArt::SetSizingInfo(const wxSize& tab_ctrl_size, if (m_fixed_tab_width > 220) m_fixed_tab_width = 220; + + m_tab_ctrl_height = tab_ctrl_size.y; } @@ -287,14 +301,20 @@ void wxAuiDefaultTabArt::DrawBackground(wxDC& dc, const wxRect& rect) { // draw background - dc.SetBrush(m_bkbrush); - dc.SetPen(*wxTRANSPARENT_PEN); - dc.DrawRectangle(-1, -1, rect.GetWidth()+2, rect.GetHeight()+2); - + wxRect r(rect.x, rect.y, rect.width+2, rect.height-3); + wxColor start_colour = StepColour(m_base_colour, 90); + wxColor end_colour = StepColour(m_base_colour, 110); + dc.GradientFillLinear(r, start_colour, end_colour, wxSOUTH); + // draw base lines - dc.SetPen(*wxGREY_PEN); - dc.DrawLine(0, rect.GetHeight()-4, rect.GetWidth(), rect.GetHeight()-4); - dc.DrawLine(0, rect.GetHeight()-1, rect.GetWidth(), rect.GetHeight()-1); + int y = rect.GetHeight(); + int w = rect.GetWidth(); + dc.SetPen(m_border_pen); + dc.DrawLine(0, y-4, w, y-4); + dc.DrawLine(0, y-1, w, y-1); + dc.SetPen(wxPen(start_colour)); + dc.DrawLine(0, y-3, w, y-3); + dc.DrawLine(0, y-2, w, y-2); } @@ -311,6 +331,7 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc, wxWindow* wnd, const wxRect& in_rect, const wxString& caption_text, + const wxBitmap& bitmap, bool active, int close_button_state, wxRect* out_tab_rect, @@ -333,9 +354,15 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc, dc.GetTextExtent(caption, &normal_textx, &normal_texty); // figure out the size of the tab - wxSize tab_size = GetTabSize(dc, wnd, caption, active, close_button_state, x_extent); - - wxCoord tab_height = tab_size.y; + wxSize tab_size = GetTabSize(dc, + wnd, + caption, + bitmap, + active, + close_button_state, + x_extent); + + wxCoord tab_height = m_tab_ctrl_height - 3; wxCoord tab_width = tab_size.x; wxCoord tab_x = in_rect.x; wxCoord tab_y = in_rect.y + in_rect.height - tab_height; @@ -343,24 +370,17 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc, caption = caption_text; - dc.SetClippingRegion(in_rect); - - // select pen, brush and font for the tab to be drawn if (active) { - dc.SetPen(m_selected_bkpen); - dc.SetBrush(m_selected_bkbrush); dc.SetFont(m_selected_font); textx = selected_textx; texty = selected_texty; } else { - dc.SetPen(m_normal_bkpen); - dc.SetBrush(m_normal_bkbrush); dc.SetFont(m_normal_font); textx = normal_textx; texty = normal_texty; @@ -369,66 +389,130 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc, // create points that will make the tab outline - wxPoint points[6]; - points[0].x = tab_x; - points[0].y = tab_y + tab_height - 4; - points[1].x = tab_x; - points[1].y = tab_y + 2; - points[2].x = tab_x + 2; - points[2].y = tab_y; - points[3].x = tab_x + tab_width - 2; - points[3].y = tab_y; - points[4].x = tab_x + tab_width; - points[4].y = tab_y + 2; - points[5].x = tab_x + tab_width; - points[5].y = tab_y + tab_height - 4; + wxPoint clip_points[6]; + clip_points[0] = wxPoint(tab_x, tab_y+tab_height-3); + clip_points[1] = wxPoint(tab_x, tab_y+2); + clip_points[2] = wxPoint(tab_x+2, tab_y); + clip_points[3] = wxPoint(tab_x+tab_width-1, tab_y); + clip_points[4] = wxPoint(tab_x+tab_width+1, tab_y+2); + clip_points[5] = wxPoint(tab_x+tab_width+1, tab_y+tab_height-3); + + // set the clipping region for the tab -- + wxRegion clipping_region(6, clip_points); + dc.SetClippingRegion(clipping_region); + + 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); + + + int drawn_tab_yoff = border_points[1].y; + int drawn_tab_height = border_points[0].y - border_points[1].y; - // draw gradient background if (active) - { - wxColour c = m_bkbrush.GetColour(); - dc.SetPen(wxPen(c)); + { + // draw active tab - int y, last_y = -1; - for (y = points[0].y; y > points[2].y; --y) - { - if (y < tab_y+(tab_height*3/5) && y != last_y) - { - last_y = y; - c = StepColour(c, 102); - dc.SetPen(wxPen(c)); - } - - dc.DrawLine(points[0].x+1, y, points[5].x, y); - } + // 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.DrawRectangle(r.x, r.y, r.width, r.height); + + // this white helps fill out the gradient at the top of the tab + dc.SetPen(*wxWHITE_PEN); + dc.SetBrush(*wxWHITE_BRUSH); + dc.DrawRectangle(r.x+2, r.y+2, r.width-3, r.height); + + // these two points help the rounded corners appear more antialiased + dc.SetPen(m_base_colour_pen); + dc.DrawPoint(r.x+2, r.y+2); + dc.DrawPoint(r.x+r.width-2, r.y+2); + + // set rectangle down a bit for gradient drawing + r.SetHeight(r.GetHeight()/2); + r.x += 2; + r.width -= 2; + r.y += r.height; + + // draw gradient background + wxColor start_color = StepColour(m_base_colour, 95); + wxColor end_color = *wxWHITE; + dc.GradientFillLinear(r, start_color, end_color, wxNORTH); } - + else + { + // draw inactive tab + + wxRect r(tab_x, tab_y+1, tab_width, tab_height-3); + + // draw base background color for inactive tabs + dc.SetPen(m_base_colour_pen); + dc.SetBrush(m_base_colour_brush); + dc.DrawRectangle(r.x, r.y, r.width, r.height); + + // start the gradent up a bit and leave the inside border inset + // by a pixel for a 3D look. Only the top half of the inactive + // tab will have a slight gradient + r.x += 2; + r.width -= 2; + r.height /= 2; + + // -- draw bottom gradient fill for glossy look + wxColor top_color = m_base_colour; + wxColor bottom_color = StepColour(top_color, 106); + dc.GradientFillLinear(r, bottom_color, top_color, wxNORTH); + } + // draw tab outline - dc.SetPen(*wxGREY_PEN); + dc.SetPen(m_border_pen); dc.SetBrush(*wxTRANSPARENT_BRUSH); - dc.DrawPolygon(6, points); + dc.DrawPolygon(6, border_points); // there are two horizontal grey lines at the bottom of the tab control, // this gets rid of the top one of those lines in the tab control if (active) { - wxColour c = m_bkbrush.GetColour(); - dc.SetPen(wxPen(c)); - dc.DrawLine(points[0].x, points[0].y, points[5].x+1, points[5].y); + wxColor start_color = StepColour(m_base_colour, 93); + dc.SetPen(wxPen(start_color)); + dc.DrawLine(border_points[0].x, + border_points[0].y, + border_points[5].x+1, + border_points[5].y); } - int text_offset; + int text_offset = tab_x + 8; int close_button_width = 0; - if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN) { close_button_width = m_active_close_bmp.GetWidth(); } - text_offset = tab_x + 8; + if (bitmap.IsOk()) + { + int bitmap_offset = tab_x + 8; + + // draw bitmap + dc.DrawBitmap(bitmap, + bitmap_offset, + drawn_tab_yoff + (drawn_tab_height/2) - (bitmap.GetHeight()/2) + 1, + true); + + text_offset = bitmap_offset + bitmap.GetWidth(); + text_offset += 3; // bitmap padding + } + else + { + text_offset = tab_x + 8; + } + wxString draw_text = ChopText(dc, caption, @@ -437,7 +521,7 @@ void wxAuiDefaultTabArt::DrawTab(wxDC& dc, // draw tab text dc.DrawText(draw_text, text_offset, - (tab_y + tab_height)/2 - (texty/2)); + drawn_tab_yoff + (drawn_tab_height)/2 - (texty/2) - 1); @@ -476,6 +560,7 @@ int wxAuiDefaultTabArt::GetIndentSize() wxSize wxAuiDefaultTabArt::GetTabSize(wxDC& dc, wxWindow* WXUNUSED(wnd), const wxString& caption, + const wxBitmap& bitmap, bool WXUNUSED(active), int close_button_state, int* x_extent) @@ -488,12 +573,24 @@ wxSize wxAuiDefaultTabArt::GetTabSize(wxDC& dc, dc.GetTextExtent(wxT("ABCDEFXj"), &tmp, &measured_texty); // add padding around the text - wxCoord tab_width = measured_textx + 16; - wxCoord tab_height = measured_texty + 10; + wxCoord tab_width = measured_textx; + wxCoord tab_height = measured_texty; + // if the close button is showing, add space for it if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN) tab_width += m_active_close_bmp.GetWidth() + 3; + // if there's a bitmap, add space for it + if (bitmap.IsOk()) + { + tab_width += bitmap.GetWidth(); + tab_width += 3; // right side bitmap padding + tab_height = wxMax(tab_height, bitmap.GetHeight()); + } + + // add padding + tab_width += 16; + tab_height += 10; if (m_flags & wxAUI_NB_TAB_FIXED_WIDTH) { @@ -622,18 +719,34 @@ int wxAuiDefaultTabArt::ShowWindowList(wxWindow* wnd, return -1; } -int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd) +int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd, + wxAuiNotebookPageArray& pages) { wxClientDC dc(wnd); dc.SetFont(m_measuring_font); - int x_ext = 0; - wxSize s = GetTabSize(dc, - wnd, - wxT("ABCDEFGHIj"), - true, - wxAUI_BUTTON_STATE_HIDDEN, - &x_ext); - return s.y+3; + + int max_y = 0; + size_t i, page_count = pages.GetCount(); + for (i = 0; i < page_count; ++i) + { + wxAuiNotebookPage& page = pages.Item(i); + + // we don't use the caption text because we don't + // want tab heights to be different in the case + // of a very short piece of text on one tab and a very + // tall piece of text on another tab + int x_ext = 0; + wxSize s = GetTabSize(dc, + wnd, + wxT("ABCDEFGHIj"), + page.bitmap, + true, + wxAUI_BUTTON_STATE_HIDDEN, + &x_ext); + max_y = wxMax(max_y, s.y); + } + + return max_y+2; } void wxAuiDefaultTabArt::SetNormalFont(const wxFont& font) @@ -755,6 +868,7 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc, wxWindow* wnd, const wxRect& in_rect, const wxString& caption_text, + const wxBitmap& bitmap, bool active, int close_button_state, wxRect* out_tab_rect, @@ -777,7 +891,13 @@ void wxAuiSimpleTabArt::DrawTab(wxDC& dc, dc.GetTextExtent(caption, &normal_textx, &normal_texty); // figure out the size of the tab - wxSize tab_size = GetTabSize(dc, wnd, caption, active, close_button_state, x_extent); + wxSize tab_size = GetTabSize(dc, + wnd, + caption, + bitmap, + active, + close_button_state, + x_extent); wxCoord tab_height = tab_size.y; wxCoord tab_width = tab_size.x; @@ -893,6 +1013,7 @@ int wxAuiSimpleTabArt::GetIndentSize() wxSize wxAuiSimpleTabArt::GetTabSize(wxDC& dc, wxWindow* WXUNUSED(wnd), const wxString& caption, + const wxBitmap& WXUNUSED(bitmap), bool WXUNUSED(active), int close_button_state, int* x_extent) @@ -1035,7 +1156,8 @@ int wxAuiSimpleTabArt::ShowWindowList(wxWindow* wnd, return -1; } -int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow* wnd) +int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow* wnd, + wxAuiNotebookPageArray& WXUNUSED(pages)) { wxClientDC dc(wnd); dc.SetFont(m_measuring_font); @@ -1043,6 +1165,7 @@ int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow* wnd) wxSize s = GetTabSize(dc, wnd, wxT("ABCDEFGHIj"), + wxNullBitmap, true, wxAUI_BUTTON_STATE_HIDDEN, &x_ext); @@ -1108,7 +1231,7 @@ void wxAuiTabContainer::SetArtProvider(wxAuiTabArt* art) } } -wxAuiTabArt* wxAuiTabContainer::GetArtProvider() +wxAuiTabArt* wxAuiTabContainer::GetArtProvider() const { return m_art; } @@ -1398,6 +1521,9 @@ void wxAuiTabContainer::SetTabOffset(size_t offset) // provide custom drawing capabilities void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) { + if (!raw_dc || !raw_dc->IsOk()) + return; + wxMemoryDC dc; wxBitmap bmp; size_t i; @@ -1408,6 +1534,8 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) bmp.Create(m_rect.GetWidth(), m_rect.GetHeight()); dc.SelectObject(bmp); + if (!dc.IsOk()) + return; // find out if size of tabs is larger than can be // afforded on screen @@ -1430,6 +1558,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) wxSize size = m_art->GetTabSize(dc, wnd, page.caption, + page.bitmap, page.active, close_button ? wxAUI_BUTTON_STATE_NORMAL : @@ -1571,7 +1700,13 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) if (offset == 0) offset += m_art->GetIndentSize(); + // prepare the tab-close-button array + // make sure tab button entries which aren't used are marked as hidden + for (i = page_count; i < m_tab_close_buttons.GetCount(); ++i) + m_tab_close_buttons.Item(i).cur_state = wxAUI_BUTTON_STATE_HIDDEN; + + // make sure there are enough tab button entries to accommodate all tabs while (m_tab_close_buttons.GetCount() < page_count) { wxAuiTabContainerButton tempbtn; @@ -1581,9 +1716,10 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) m_tab_close_buttons.Add(tempbtn); } + + // buttons before the tab offset must be set to hidden for (i = 0; i < m_tab_offset; ++i) { - // buttons before the tab offset must be set to hidden m_tab_close_buttons.Item(i).cur_state = wxAUI_BUTTON_STATE_HIDDEN; } @@ -1628,13 +1764,11 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) if (rect.width <= 0) break; - - - m_art->DrawTab(dc, wnd, rect, page.caption, + page.bitmap, page.active, tab_button.cur_state, &page.rect, @@ -1651,6 +1785,14 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) offset += x_extent; } + + // make sure to deactivate buttons which are off the screen to the right + for (++i; i < m_tab_close_buttons.GetCount(); ++i) + { + m_tab_close_buttons.Item(i).cur_state = wxAUI_BUTTON_STATE_HIDDEN; + } + + // draw the active tab again so it stands in the foreground if (active >= m_tab_offset && active < m_pages.GetCount()) { @@ -1671,6 +1813,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) wnd, active_rect, page.caption, + page.bitmap, page.active, tab_button.cur_state, &page.rect, @@ -1731,7 +1874,9 @@ bool wxAuiTabContainer::ButtonHitTest(int x, int y, for (i = 0; i < button_count; ++i) { wxAuiTabContainerButton& button = m_buttons.Item(i); - if (button.rect.Contains(x,y)) + if (button.rect.Contains(x,y) && + !(button.cur_state & (wxAUI_BUTTON_STATE_HIDDEN | + wxAUI_BUTTON_STATE_DISABLED))) { if (hit) *hit = &button; @@ -1743,7 +1888,9 @@ bool wxAuiTabContainer::ButtonHitTest(int x, int y, for (i = 0; i < button_count; ++i) { wxAuiTabContainerButton& button = m_tab_close_buttons.Item(i); - if (button.rect.Contains(x,y)) + if (button.rect.Contains(x,y) && + !(button.cur_state & (wxAUI_BUTTON_STATE_HIDDEN | + wxAUI_BUTTON_STATE_DISABLED))) { if (hit) *hit = &button; @@ -1829,6 +1976,7 @@ wxAuiTabCtrl::wxAuiTabCtrl(wxWindow* parent, m_click_pt = wxDefaultPosition; m_is_dragging = false; m_hover_button = NULL; + m_pressed_button = NULL; } wxAuiTabCtrl::~wxAuiTabCtrl() @@ -1862,19 +2010,22 @@ void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt) m_click_pt = wxDefaultPosition; m_is_dragging = false; m_click_tab = NULL; + m_pressed_button = NULL; wxWindow* wnd; if (TabHitTest(evt.m_x, evt.m_y, &wnd)) { - if (m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) - m_hover_button = NULL; + int new_selection = GetIdxFromWindow(wnd); - wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId); - e.SetSelection(GetIdxFromWindow(wnd)); - e.SetOldSelection(GetActivePage()); - e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + if (new_selection != GetActivePage()) + { + wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId); + e.SetSelection(new_selection); + e.SetOldSelection(GetActivePage()); + e.SetEventObject(this); + GetEventHandler()->ProcessEvent(e); + } m_click_pt.x = evt.m_x; m_click_pt.y = evt.m_y; @@ -1883,13 +2034,14 @@ void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt) if (m_hover_button) { - m_hover_button->cur_state = wxAUI_BUTTON_STATE_PRESSED; + m_pressed_button = m_hover_button; + m_pressed_button->cur_state = wxAUI_BUTTON_STATE_PRESSED; Refresh(); Update(); } } -void wxAuiTabCtrl::OnLeftUp(wxMouseEvent&) +void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt) { if (GetCapture() == this) ReleaseMouse(); @@ -1904,19 +2056,31 @@ void wxAuiTabCtrl::OnLeftUp(wxMouseEvent&) return; } - if (m_hover_button) + if (m_pressed_button) { - m_hover_button->cur_state = wxAUI_BUTTON_STATE_HOVER; + // make sure we're still clicking the button + wxAuiTabContainerButton* button = NULL; + if (!ButtonHitTest(evt.m_x, evt.m_y, &button)) + return; + + if (button != m_pressed_button) + { + m_pressed_button = NULL; + return; + } + Refresh(); Update(); - if (!(m_hover_button->cur_state & wxAUI_BUTTON_STATE_DISABLED)) + if (!(m_pressed_button->cur_state & wxAUI_BUTTON_STATE_DISABLED)) { wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON, m_windowId); - evt.SetInt(m_hover_button->id); + evt.SetInt(m_pressed_button->id); evt.SetEventObject(this); GetEventHandler()->ProcessEvent(evt); } + + m_pressed_button = NULL; } m_click_pt = wxDefaultPosition; @@ -2237,26 +2401,45 @@ void wxAuiNotebook::SetArtProvider(wxAuiTabArt* art) { m_tabs.SetArtProvider(art); - // choose a default for the tab height - m_tab_ctrl_height = art->GetBestTabCtrlSize(this); - - wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes(); - size_t i, pane_count = all_panes.GetCount(); - for (i = 0; i < pane_count; ++i) + SetTabCtrlHeight(CalculateTabCtrlHeight()); +} + +void wxAuiNotebook::SetTabCtrlHeight(int height) +{ + // if the tab control height needs to change, update + // all of our tab controls with the new height + if (m_tab_ctrl_height != height) { - 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(); + wxAuiTabArt* art = m_tabs.GetArtProvider(); + + 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(); + } } - } -wxAuiTabArt* wxAuiNotebook::GetArtProvider() +int wxAuiNotebook::CalculateTabCtrlHeight() +{ + // find out new best tab height + wxAuiTabArt* art = m_tabs.GetArtProvider(); + + return art->GetBestTabCtrlSize(this, m_tabs.GetPages()); +} + + +wxAuiTabArt* wxAuiNotebook::GetArtProvider() const { return m_tabs.GetArtProvider(); } @@ -2321,6 +2504,7 @@ bool wxAuiNotebook::InsertPage(size_t page_idx, else active_tabctrl->InsertPage(page, info, page_idx); + SetTabCtrlHeight(CalculateTabCtrlHeight()); DoSizing(); active_tabctrl->DoShowHide(); @@ -2345,7 +2529,6 @@ bool wxAuiNotebook::DeletePage(size_t page_idx) if (!RemovePage(page_idx)) return false; - // actually destroy the window now if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame))) { @@ -2422,6 +2605,15 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) return true; } +// GetPageIndex() returns the index of the page, or -1 if the +// page could not be located in the notebook +int wxAuiNotebook::GetPageIndex(wxWindow* page_wnd) const +{ + return m_tabs.GetIdxFromWindow(page_wnd); +} + + + // SetPageText() changes the tab caption of the specified page bool wxAuiNotebook::SetPageText(size_t page_idx, const wxString& text) { @@ -2446,6 +2638,34 @@ bool wxAuiNotebook::SetPageText(size_t page_idx, const wxString& text) return true; } + +bool wxAuiNotebook::SetPageBitmap(size_t page_idx, const wxBitmap& bitmap) +{ + if (page_idx >= m_tabs.GetPageCount()) + return false; + + // update our own tab catalog + wxAuiNotebookPage& page_info = m_tabs.GetPage(page_idx); + page_info.bitmap = bitmap; + + // tab height might have changed + SetTabCtrlHeight(CalculateTabCtrlHeight()); + + // update what's on screen + wxAuiTabCtrl* ctrl; + int ctrl_idx; + if (FindTab(page_info.window, &ctrl, &ctrl_idx)) + { + wxAuiNotebookPage& info = ctrl->GetPage(ctrl_idx); + info.bitmap = bitmap; + ctrl->Refresh(); + ctrl->Update(); + } + + return true; +} + + // GetSelection() returns the index of the currently active page int wxAuiNotebook::GetSelection() const { @@ -2465,12 +2685,14 @@ size_t wxAuiNotebook::SetSelection(size_t new_page) evt.SetEventObject(this); if (!GetEventHandler()->ProcessEvent(evt) || evt.IsAllowed()) { + int old_curpage = m_curpage; + m_curpage = new_page; + // program allows the page change evt.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED); (void)GetEventHandler()->ProcessEvent(evt); - wxAuiTabCtrl* ctrl; int ctrl_idx; if (FindTab(wnd, &ctrl, &ctrl_idx)) @@ -2481,8 +2703,6 @@ size_t wxAuiNotebook::SetSelection(size_t new_page) DoSizing(); ctrl->DoShowHide(); - int old_curpage = m_curpage; - m_curpage = new_page; // set fonts @@ -2707,8 +2927,12 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt) { wxWindow* tab_ctrl = ::wxFindWindowAtPoint(screen_pt); + // if we aren't over any window, stop here + if (!tab_ctrl) + return; + // make sure we are not over the hint window - if (tab_ctrl && !tab_ctrl->IsKindOf(CLASSINFO(wxFrame))) + if (!tab_ctrl->IsKindOf(CLASSINFO(wxFrame))) { while (tab_ctrl) { @@ -2723,12 +2947,20 @@ void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt) if (nb != this) { - wxRect hint_rect = tab_ctrl->GetRect(); + wxRect hint_rect = tab_ctrl->GetClientRect(); tab_ctrl->ClientToScreen(&hint_rect.x, &hint_rect.y); m_mgr.ShowHint(hint_rect); return; } - + } + } + else + { + if (!dest_tabs) + { + // we are either over a hint window, or not over a tab + // window, and there is no where to drag to, so exit + return; } } }