X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/22a35096a0a9c3fe4d3d32b8d68a361126ef9677..64f8f94ca0797f2d4a0c7daf34500ccc23c7d83e:/src/aui/auibook.cpp diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 0b67e2e8f9..5d7b97897f 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -45,17 +45,8 @@ DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION) IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxEvent) -// -- wxAuiTabContainer class implementation -- -// wxAuiTabContainer is a class which contains information about each -// tab. It also can render an entire tab control to a specified DC. -// It's not a window class itself, because this code will be used by -// the wxFrameMananger, where it is disadvantageous to have separate -// windows for each tab control in the case of "docked tabs" - -// A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window -// which can be used as a tab control in the normal sense. // This functions are here for this proof of concept @@ -111,7 +102,10 @@ static void DrawButton(wxDC& dc, -wxAuiTabContainer::wxAuiTabContainer() + +// -- wxDefaultTabArt class implementation -- + +wxDefaultTabArt::wxDefaultTabArt() { m_normal_font = *wxNORMAL_FONT; m_selected_font = *wxNORMAL_FONT; @@ -131,23 +125,192 @@ wxAuiTabContainer::wxAuiTabContainer() m_selected_bkpen = wxPen(selectedtab_colour); } +wxDefaultTabArt::~wxDefaultTabArt() +{ +} + +void wxDefaultTabArt::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); + + // draw base line + dc->SetPen(*wxGREY_PEN); + dc->DrawLine(0, rect.GetHeight()-1, rect.GetWidth(), rect.GetHeight()-1); +} + +// DrawTab() draws an individual tab. +// +// dc - output dc +// in_rect - rectangle the tab should be confined to +// caption - tab's caption +// active - whether or not the tab is active +// out_rect - actual output rectangle +// x_extent - the advance x; where the next tab should start + +void wxDefaultTabArt::DrawTab(wxDC* dc, + const wxRect& in_rect, + const wxString& caption_text, + bool active, + wxRect* out_rect, + int* x_extent) +{ + wxCoord normal_textx, normal_texty; + wxCoord selected_textx, selected_texty; + wxCoord measured_textx, measured_texty; + wxCoord textx, texty; + + + // if the caption is empty, measure some temporary text + wxString caption = caption_text; + if (caption_text.empty()) + caption = wxT("Xj"); + + // measure text + dc->SetFont(m_measuring_font); + dc->GetTextExtent(caption, &measured_textx, &measured_texty); + + dc->SetFont(m_selected_font); + dc->GetTextExtent(caption, &selected_textx, &selected_texty); + + dc->SetFont(m_normal_font); + dc->GetTextExtent(caption, &normal_textx, &normal_texty); + + caption = caption_text; + + wxCoord tab_height = measured_texty + 4; + wxCoord tab_width = measured_textx + tab_height + 5; + wxCoord tab_x = in_rect.x; + wxCoord tab_y = in_rect.y + in_rect.height - tab_height; + + + // 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; + } + + + // -- draw line -- + + wxPoint points[7]; + points[0].x = tab_x; + points[0].y = tab_y + tab_height - 1; + points[1].x = tab_x + tab_height - 3; + points[1].y = tab_y + 2; + points[2].x = tab_x + tab_height + 3; + 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 - 1; + points[6] = points[0]; + + + dc->DrawPolygon(6, points); + + dc->SetPen(*wxGREY_PEN); + + //dc->DrawLines(active ? 6 : 7, points); + dc->DrawLines(7, points); + + // -- draw text -- + + dc->DrawText(caption, + tab_x + (tab_height/3) + (tab_width/2) - (textx/2), + tab_y + tab_height - texty - 2); + + *out_rect = wxRect(tab_x, tab_y, tab_width, tab_height); + *x_extent = tab_width - (tab_height/2) - 1; +} + + +void wxDefaultTabArt::SetNormalFont(const wxFont& font) +{ + m_normal_font = font; +} + +void wxDefaultTabArt::SetSelectedFont(const wxFont& font) +{ + m_selected_font = font; +} + +void wxDefaultTabArt::SetMeasuringFont(const wxFont& font) +{ + m_measuring_font = font; +} + + + + + + +// -- wxAuiTabContainer class implementation -- + + +// wxAuiTabContainer is a class which contains information about each +// tab. It also can render an entire tab control to a specified DC. +// It's not a window class itself, because this code will be used by +// the wxFrameMananger, where it is disadvantageous to have separate +// windows for each tab control in the case of "docked tabs" + +// A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window +// which can be used as a tab control in the normal sense. + + +wxAuiTabContainer::wxAuiTabContainer() +{ + m_art = new wxDefaultTabArt; +} + wxAuiTabContainer::~wxAuiTabContainer() { + delete m_art; +} + +void wxAuiTabContainer::SetArtProvider(wxTabArt* art) +{ + delete m_art; + m_art = art; +} + +wxTabArt* wxAuiTabContainer::GetArtProvider() +{ + return m_art; } void wxAuiTabContainer::SetNormalFont(const wxFont& font) { - m_normal_font = font; + m_art->SetNormalFont(font); } void wxAuiTabContainer::SetSelectedFont(const wxFont& font) { - m_selected_font = font; + m_art->SetSelectedFont(font); } void wxAuiTabContainer::SetMeasuringFont(const wxFont& font) { - m_measuring_font = font; + m_art->SetMeasuringFont(font); } void wxAuiTabContainer::SetRect(const wxRect& rect) @@ -289,11 +452,12 @@ size_t wxAuiTabContainer::GetPageCount() const return m_pages.GetCount(); } -void wxAuiTabContainer::AddButton(int id, const wxBitmap& bmp) +void wxAuiTabContainer::AddButton(int id, int location, const wxBitmap& bmp) { wxAuiTabContainerButton button; button.id = id; button.bitmap = bmp; + button.location = location; button.cur_state = wxAUI_BUTTON_STATE_NORMAL; m_buttons.Add(button); @@ -301,130 +465,74 @@ void wxAuiTabContainer::AddButton(int id, const wxBitmap& bmp) -// DrawTab() draws an individual tab. -// As it is virtual it may be overridden. -// -// dc - output dc -// in_rect - rectangle the tab should be confined to -// caption - tab's caption -// active - whether or not the tab is active -// out_rect - actual output rectangle -// x_extent - the advance x; where the next tab should start - -void wxAuiTabContainer::DrawTab(wxDC* dc, - const wxRect& in_rect, - const wxString& caption_text, - bool active, - wxRect* out_rect, - int* x_extent) +// Render() renders the tab catalog to the specified DC +// It is a virtual function and can be overridden to +// provide custom drawing capabilities +void wxAuiTabContainer::Render(wxDC* raw_dc) { - wxCoord normal_textx, normal_texty; - wxCoord selected_textx, selected_texty; - wxCoord measured_textx, measured_texty; - wxCoord textx, texty; - - - // if the caption is empty, measure some temporary text - wxString caption = caption_text; - if (caption_text.empty()) - caption = wxT("Xj"); - - // measure text - dc->SetFont(m_measuring_font); - dc->GetTextExtent(caption, &measured_textx, &measured_texty); - - dc->SetFont(m_selected_font); - dc->GetTextExtent(caption, &selected_textx, &selected_texty); - - dc->SetFont(m_normal_font); - dc->GetTextExtent(caption, &normal_textx, &normal_texty); - - caption = caption_text; - - wxCoord tab_height = measured_texty + 4; - wxCoord tab_width = measured_textx + tab_height + 5; - wxCoord tab_x = in_rect.x; - wxCoord tab_y = in_rect.y + in_rect.height - tab_height; + wxMemoryDC dc; + wxBitmap bmp; + bmp.Create(m_rect.GetWidth(), m_rect.GetHeight()); + dc.SelectObject(bmp); + m_art->DrawBackground(&dc, m_rect); - // select pen, brush and font for the tab to be drawn + int offset = 0; + size_t i; - if (active) - { - dc->SetPen(m_selected_bkpen); - dc->SetBrush(m_selected_bkbrush); - dc->SetFont(m_selected_font); - textx = selected_textx; - texty = selected_texty; - } - else + // draw the buttons on the right side + offset = m_rect.x + m_rect.width; + size_t button_count = m_buttons.GetCount(); + for (i = 0; i < button_count; ++i) { - dc->SetPen(m_normal_bkpen); - dc->SetBrush(m_normal_bkbrush); - dc->SetFont(m_normal_font); - textx = normal_textx; - texty = normal_texty; - } - - - // -- draw line -- - - wxPoint points[7]; - points[0].x = tab_x; - points[0].y = tab_y + tab_height - 1; - points[1].x = tab_x + tab_height - 3; - points[1].y = tab_y + 2; - points[2].x = tab_x + tab_height + 3; - 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 - 1; - points[6] = points[0]; - - - dc->DrawPolygon(6, points); + wxAuiTabContainerButton& button = m_buttons.Item(button_count - i - 1); + + if (button.location != wxRIGHT) + continue; + + wxRect button_rect(offset - button.bitmap.GetWidth(), 1, + button.bitmap.GetWidth(), button.bitmap.GetHeight()); - dc->SetPen(*wxGREY_PEN); + button.rect = button_rect; - //dc->DrawLines(active ? 6 : 7, points); - dc->DrawLines(7, points); + DrawButton(dc, button.rect, button.bitmap, + //m_bkbrush.GetColour(), + *wxWHITE, + button.cur_state); - // -- draw text -- + offset -= button.bitmap.GetWidth(); + } - dc->DrawText(caption, - tab_x + (tab_height/3) + (tab_width/2) - (textx/2), - tab_y + tab_height - texty - 2); - *out_rect = wxRect(tab_x, tab_y, tab_width, tab_height); - *x_extent = tab_width - (tab_height/2) - 1; -} + offset = 0; + + // draw the buttons on the left side -// Render() renders the tab catalog to the specified DC -// It is a virtual function and can be overridden to -// provide custom drawing capabilities -void wxAuiTabContainer::Render(wxDC* raw_dc) -{ - wxMemoryDC dc; - wxBitmap bmp; - bmp.Create(m_rect.GetWidth(), m_rect.GetHeight()); - dc.SelectObject(bmp); + for (i = 0; i < button_count; ++i) + { + wxAuiTabContainerButton& button = m_buttons.Item(button_count - i - 1); + + if (button.location != wxLEFT) + continue; + + wxRect button_rect(offset, 1, + button.bitmap.GetWidth(), + button.bitmap.GetHeight()); - // draw background - dc.SetBrush(m_bkbrush); - dc.SetPen(*wxTRANSPARENT_PEN); - dc.DrawRectangle(-1, -1, m_rect.GetWidth()+2, m_rect.GetHeight()+2); + button.rect = button_rect; - // draw base line - dc.SetPen(*wxGREY_PEN); - dc.DrawLine(0, m_rect.GetHeight()-1, m_rect.GetWidth(), m_rect.GetHeight()-1); + DrawButton(dc, button.rect, button.bitmap, + //m_bkbrush.GetColour(), + *wxWHITE, + button.cur_state); + offset += button.bitmap.GetWidth(); + } - size_t i, page_count = m_pages.GetCount(); - int offset = 0; + + // draw the tabs + size_t page_count = m_pages.GetCount(); size_t active = 999; int active_offset = 0; @@ -441,7 +549,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) rect.x = offset; - DrawTab(&dc, + m_art->DrawTab(&dc, rect, page.caption, page.active, @@ -463,7 +571,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) wxAuiNotebookPage& page = m_pages.Item(active); rect.x = active_offset; - DrawTab(&dc, + m_art->DrawTab(&dc, rect, page.caption, page.active, @@ -471,25 +579,6 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) &x_extent); } - // draw the buttons - offset = m_rect.x + m_rect.width; - size_t button_count = m_buttons.GetCount(); - for (i = 0; i < button_count; ++i) - { - wxAuiTabContainerButton& button = m_buttons.Item(button_count - i - 1); - - wxRect button_rect(offset - button.bitmap.GetWidth(), 1, - button.bitmap.GetWidth(), button.bitmap.GetHeight()); - - button.rect = button_rect; - - DrawButton(dc, button.rect, button.bitmap, - m_bkbrush.GetColour(), - button.cur_state); - - offset -= button.bitmap.GetWidth(); - } - raw_dc->Blit(m_rect.x, m_rect.y, m_rect.GetWidth(), m_rect.GetHeight(), &dc, 0, 0); } @@ -635,7 +724,7 @@ wxAuiTabCtrl::wxAuiTabCtrl(wxWindow* parent, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; #endif - AddButton(101, BitmapFromBits(close_bits, 16, 16, *wxBLACK)); + AddButton(101, wxRIGHT, BitmapFromBits(close_bits, 16, 16, *wxBLACK)); } @@ -729,6 +818,14 @@ void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt) wxAuiTabContainerButton* button; if (ButtonHitTest(pos.x, pos.y, &button)) { + if (m_hover_button && button != m_hover_button) + { + m_hover_button->cur_state = wxAUI_BUTTON_STATE_NORMAL; + m_hover_button = NULL; + Refresh(); + Update(); + } + if (button->cur_state != wxAUI_BUTTON_STATE_HOVER) { button->cur_state = wxAUI_BUTTON_STATE_HOVER; @@ -977,6 +1074,16 @@ wxAuiMultiNotebook::~wxAuiMultiNotebook() m_mgr.UnInit(); } +void wxAuiMultiNotebook::SetArtProvider(wxTabArt* art) +{ + m_tabs.SetArtProvider(art); +} + +wxTabArt* wxAuiMultiNotebook::GetArtProvider() +{ + return m_tabs.GetArtProvider(); +} + bool wxAuiMultiNotebook::AddPage(wxWindow* page, const wxString& caption, bool select, @@ -1028,9 +1135,9 @@ bool wxAuiMultiNotebook::InsertPage(size_t page_idx, // DeletePage() removes a tab from the multi-notebook, // and destroys the window as well bool wxAuiMultiNotebook::DeletePage(size_t page_idx) -{ +{ wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx); - + wxWindow* new_active = NULL; // find out which onscreen tab ctrl owns this tab wxAuiTabCtrl* ctrl; @@ -1045,33 +1152,24 @@ bool wxAuiMultiNotebook::DeletePage(size_t page_idx) if (new_idx >= 0 && new_idx < (int)ctrl->GetPageCount()) { - wxWindow* new_wnd = ctrl->GetWindowFromIdx(new_idx); - int main_idx = m_tabs.GetIdxFromWindow(new_wnd); - wxASSERT(main_idx != -1); - SetSelection(main_idx); + new_active = ctrl->GetWindowFromIdx(new_idx); } else { // set the active page to the first page that // isn't the one being deleted - bool found = false; size_t i, page_count = m_tabs.GetPageCount(); for (i = 0; i < page_count; ++i) { wxWindow* w = m_tabs.GetWindowFromIdx(i); if (wnd != w) { - found = true; - SetSelection(i); + new_active = m_tabs.GetWindowFromIdx(i); break; } } - - if (!found) - m_curpage = -1; } - // remove the tab from main catalog if (!m_tabs.RemovePage(wnd)) return false; @@ -1094,6 +1192,13 @@ bool wxAuiMultiNotebook::DeletePage(size_t page_idx) RemoveEmptyTabFrames(); + // set new active pane + if (new_active) + { + m_curpage = -1; + SetSelection(m_tabs.GetIdxFromWindow(new_active)); + } + return true; }