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
This commit is contained in:
@@ -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);
|
||||
|
@@ -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,25 +125,190 @@ wxAuiTabContainer::wxAuiTabContainer()
|
||||
m_selected_bkpen = wxPen(selectedtab_colour);
|
||||
}
|
||||
|
||||
wxAuiTabContainer::~wxAuiTabContainer()
|
||||
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);
|
||||
}
|
||||
|
||||
void wxAuiTabContainer::SetNormalFont(const wxFont& font)
|
||||
// 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 wxAuiTabContainer::SetSelectedFont(const wxFont& font)
|
||||
void wxDefaultTabArt::SetSelectedFont(const wxFont& font)
|
||||
{
|
||||
m_selected_font = font;
|
||||
}
|
||||
|
||||
void wxAuiTabContainer::SetMeasuringFont(const wxFont& 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_art->SetNormalFont(font);
|
||||
}
|
||||
|
||||
void wxAuiTabContainer::SetSelectedFont(const wxFont& font)
|
||||
{
|
||||
m_art->SetSelectedFont(font);
|
||||
}
|
||||
|
||||
void wxAuiTabContainer::SetMeasuringFont(const wxFont& font)
|
||||
{
|
||||
m_art->SetMeasuringFont(font);
|
||||
}
|
||||
|
||||
void wxAuiTabContainer::SetRect(const wxRect& rect)
|
||||
{
|
||||
m_rect = 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,
|
||||
|
Reference in New Issue
Block a user