From 3f69756e3d68cc8a04b95c95df211295d2ac0ec8 Mon Sep 17 00:00:00 2001 From: Benjamin Williams Date: Sat, 28 Oct 2006 15:20:10 +0000 Subject: [PATCH] wxaui multi-notebook now uses a tab art provider which allows for dynamically switchable notebook themes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42576 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/aui/auibook.h | 81 ++++++++-- src/aui/auibook.cpp | 313 +++++++++++++++++++++++---------------- 2 files changed, 254 insertions(+), 140 deletions(-) diff --git a/include/wx/aui/auibook.h b/include/wx/aui/auibook.h index 5c0b00f549..3606776512 100644 --- a/include/wx/aui/auibook.h +++ b/include/wx/aui/auibook.h @@ -27,6 +27,66 @@ #include "wx/control.h" +// tab art class + + +class wxTabArt +{ +public: + + virtual void DrawBackground( + wxDC* dc, + const wxRect& rect) = 0; + + virtual void DrawTab(wxDC* dc, + const wxRect& in_rect, + const wxString& caption, + bool active, + wxRect* out_rect, + int* x_extent) = 0; + + virtual void SetNormalFont(const wxFont& font) = 0; + virtual void SetSelectedFont(const wxFont& font) = 0; + virtual void SetMeasuringFont(const wxFont& font) = 0; +}; + + +class wxDefaultTabArt : public wxTabArt +{ + +public: + + wxDefaultTabArt(); + + void DrawBackground( + wxDC* dc, + const wxRect& rect); + + void DrawTab(wxDC* dc, + const wxRect& in_rect, + const wxString& caption, + bool active, + wxRect* out_rect, + int* x_extent); + + void SetNormalFont(const wxFont& font); + void SetSelectedFont(const wxFont& font); + void SetMeasuringFont(const wxFont& font); + +private: + + wxFont m_normal_font; + wxFont m_selected_font; + wxFont m_measuring_font; + wxPen m_normal_bkpen; + wxPen m_selected_bkpen; + wxBrush m_normal_bkbrush; + wxBrush m_selected_bkbrush; + wxBrush m_bkbrush; +}; + + + // event declarations/classes class WXDLLIMPEXP_AUI wxAuiNotebookEvent : public wxNotifyEvent @@ -98,6 +158,9 @@ public: wxAuiTabContainer(); virtual ~wxAuiTabContainer(); + void SetArtProvider(wxTabArt* art); + wxTabArt* GetArtProvider(); + bool AddPage(wxWindow* page, const wxAuiNotebookPage& info); bool InsertPage(wxWindow* page, const wxAuiNotebookPage& info, size_t idx); bool RemovePage(wxWindow* page); @@ -123,25 +186,12 @@ protected: virtual void Render(wxDC* dc); - virtual void DrawTab(wxDC* dc, - const wxRect& in_rect, - const wxString& caption, - bool active, - wxRect* out_rect, - int* x_extent); private: + wxTabArt* m_art; wxAuiNotebookPageArray m_pages; wxAuiTabContainerButtonArray m_buttons; wxRect m_rect; - wxFont m_normal_font; - wxFont m_selected_font; - wxFont m_measuring_font; - wxPen m_normal_bkpen; - wxPen m_selected_bkpen; - wxBrush m_normal_bkbrush; - wxBrush m_selected_bkbrush; - wxBrush m_bkbrush; }; @@ -223,6 +273,9 @@ public: size_t GetPageCount() const; wxWindow* GetPage(size_t page_idx) const; + void SetArtProvider(wxTabArt* art); + wxTabArt* GetArtProvider(); + protected: wxAuiTabCtrl* GetTabCtrlFromPoint(const wxPoint& pt); diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 12511fae34..e0d1752d9d 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,188 @@ wxAuiTabContainer::wxAuiTabContainer() m_selected_bkpen = wxPen(selectedtab_colour); } +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) @@ -301,108 +460,6 @@ 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) -{ - 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; -} - - // Render() renders the tab catalog to the specified DC // It is a virtual function and can be overridden to // provide custom drawing capabilities @@ -413,15 +470,8 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) bmp.Create(m_rect.GetWidth(), m_rect.GetHeight()); dc.SelectObject(bmp); - // draw background - dc.SetBrush(m_bkbrush); - dc.SetPen(*wxTRANSPARENT_PEN); - dc.DrawRectangle(-1, -1, m_rect.GetWidth()+2, m_rect.GetHeight()+2); - - // draw base line - dc.SetPen(*wxGREY_PEN); - dc.DrawLine(0, m_rect.GetHeight()-1, m_rect.GetWidth(), m_rect.GetHeight()-1); + m_art->DrawBackground(&dc, m_rect); size_t i, page_count = m_pages.GetCount(); int offset = 0; @@ -441,7 +491,7 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) rect.x = offset; - DrawTab(&dc, + m_art->DrawTab(&dc, rect, page.caption, page.active, @@ -463,7 +513,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, @@ -484,7 +534,8 @@ void wxAuiTabContainer::Render(wxDC* raw_dc) button.rect = button_rect; DrawButton(dc, button.rect, button.bitmap, - m_bkbrush.GetColour(), + //m_bkbrush.GetColour(), + *wxWHITE, button.cur_state); offset -= button.bitmap.GetWidth(); @@ -977,6 +1028,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, -- 2.45.2