Created
March 16, 2024 17:24
-
-
Save vadz/2fba5f0f48cbea44477096f3990fe0d9 to your computer and use it in GitHub Desktop.
Example of using custom tab art with wxAUI
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <wx/app.h> | |
#include <wx/dc.h> | |
#include <wx/frame.h> | |
#include <wx/panel.h> | |
#include <wx/sizer.h> | |
#include <wx/textctrl.h> | |
#include <wx/aui/aui.h> | |
class TestDockArt : public wxAuiDefaultDockArt { | |
public: | |
void DrawCaption(wxDC& dc, | |
wxWindow* window, | |
const wxString& text, | |
const wxRect& rect, | |
wxAuiPaneInfo& pane) | |
{ | |
dc.SetBrush(*wxBLUE); | |
dc.DrawRectangle(rect); | |
dc.SetTextForeground(*wxYELLOW); | |
dc.DrawText(text, rect.x + window->FromDIP(5), rect.y); | |
} | |
}; | |
class TestTabArt : public wxAuiGenericTabArt | |
{ | |
public: | |
wxAuiTabArt* Clone() override | |
{ | |
return new TestTabArt{*this}; | |
} | |
void | |
DrawBackground(wxDC& dc, | |
wxWindow* WXUNUSED(wnd), | |
const wxRect& rect) override | |
{ | |
dc.SetBrush(*wxBLACK_BRUSH); | |
dc.DrawRectangle(rect); | |
} | |
void | |
DrawTab(wxDC& dc, | |
wxWindow* wnd, | |
const wxAuiNotebookPage& pane, | |
const wxRect& inRect, | |
int closeButtonState, | |
wxRect* outTabRect, | |
wxRect* WXUNUSED(outButtonRect), | |
int* xExtent) override | |
{ | |
const wxSize tabSize = GetTabSize(dc, wnd, pane.caption, pane.bitmap, | |
pane.active, closeButtonState, | |
xExtent); | |
*outTabRect = wxRect(inRect.GetPosition(), tabSize); | |
// To draw a semi-rounded (on top only) rectangle, make it much higher | |
// than necessary, so that the bottom round corners are chopped off. | |
wxRect rect = *outTabRect; | |
rect.height *= 2; | |
dc.SetBrush(pane.active ? *wxBLUE_BRUSH : *wxTRANSPARENT_BRUSH); | |
dc.DrawRoundedRectangle(rect, wnd->FromDIP(8)); | |
rect.height /= 2; | |
// Use some horizontal padding. | |
rect.Deflate(wnd->FromDIP(5), 0); | |
// Draw the bitmap, if any. | |
if ( pane.bitmap.IsOk() ) | |
{ | |
const auto& bitmap = pane.bitmap.GetBitmapFor(wnd); | |
dc.DrawBitmap(bitmap, | |
rect.x, | |
rect.y + (rect.height - bitmap.GetLogicalHeight()) / 2, | |
true /* use mask */); | |
rect.Deflate(bitmap.GetLogicalWidth() + wnd->FromDIP(5), 0); | |
} | |
// Draw the text. | |
dc.SetTextForeground(*wxWHITE); | |
dc.SetFont(pane.active ? m_selectedFont : m_normalFont); | |
dc.DrawLabel(pane.caption, rect, wxALIGN_CENTER_VERTICAL); | |
// Finally, draw the close button. | |
if ( closeButtonState != wxAUI_BUTTON_STATE_HIDDEN ) | |
{ | |
const wxBitmapBundle bb(pane.active ? m_activeCloseBmp | |
: m_disabledCloseBmp); | |
const wxBitmap bitmap = bb.GetBitmapFor(wnd); | |
rect.x = inRect.x + tabSize.x - bitmap.GetLogicalWidth() - wnd->FromDIP(5); | |
rect.width = bitmap.GetLogicalWidth(); | |
// TODO: account for button state. | |
dc.DrawBitmap(bitmap, | |
rect.x, | |
rect.y + (rect.height - bitmap.GetLogicalHeight()) / 2, | |
true /* use mask */); | |
} | |
} | |
wxSize | |
GetTabSize(wxDC& dc, | |
wxWindow* wnd, | |
const wxString& caption, | |
const wxBitmapBundle& bitmap, | |
bool WXUNUSED(active), | |
int closeButtonState, | |
int* xExtent) override | |
{ | |
dc.SetFont(m_measuringFont); | |
wxSize size = dc.GetTextExtent(caption); | |
// Account for the close button. | |
if ( closeButtonState != wxAUI_BUTTON_STATE_HIDDEN ) | |
{ | |
size.x += m_activeCloseBmp.GetBitmapFor(wnd).GetLogicalWidth(); | |
size.x += wnd->FromDIP(10); | |
} | |
// Account for the bitmap, if any. | |
if ( bitmap.IsOk() ) | |
{ | |
const wxSize bitmapSize = bitmap.GetPreferredLogicalSizeFor(wnd); | |
size.x += bitmapSize.x; | |
size.x += wnd->FromDIP(10); | |
if ( bitmapSize.y > size.y ) | |
size.y = bitmapSize.y; | |
} | |
// Add some padding. | |
size += wnd->FromDIP(wxSize(20, 8)); | |
*xExtent = size.x; | |
return size; | |
} | |
}; | |
class TestPanel : public wxPanel { | |
public: | |
explicit TestPanel(wxWindow* parent) : wxPanel(parent, wxID_ANY) { | |
m_manager.SetManagedWindow(this); | |
m_manager.SetArtProvider(new TestDockArt); | |
auto nb = new wxAuiNotebook(this); | |
nb->AddPage(new wxTextCtrl(nb, wxID_ANY, "Welcome to the first page"), "First"); | |
nb->AddPage(new wxTextCtrl(nb, wxID_ANY, "And another one"), "Second"); | |
nb->AddPage(new wxTextCtrl(nb, wxID_ANY, "Last page, promised"), "Last"); | |
nb->SetArtProvider(new TestTabArt); | |
m_manager.AddPane(nb, wxAuiPaneInfo().CenterPane().PaneBorder(false)); | |
m_manager.AddPane(new wxTextCtrl(this, wxID_ANY, "Left pane"), wxAuiPaneInfo().Left().Layer(1).MinSize(FromDIP(wxSize(200, 100))).Caption("Left pane").CloseButton()); | |
m_manager.AddPane(new wxTextCtrl(this, wxID_ANY, "Bottom pane"), wxAuiPaneInfo().Bottom().Layer(2).MinSize(FromDIP(wxSize(200, 100))).Caption("Bottom pane").MaximizeButton()); | |
m_manager.Update(); | |
} | |
private: | |
wxAuiManager m_manager; | |
}; | |
class TestApp : public wxApp { | |
public: | |
bool OnInit() override { | |
auto f = new wxFrame(nullptr, wxID_ANY, "Window containing AUI panel"); | |
auto t = new wxTextCtrl(f, wxID_ANY, "Just a text", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); | |
auto p = new TestPanel(f); | |
auto s = new wxBoxSizer(wxHORIZONTAL); | |
s->Add(t, wxSizerFlags().Expand()); | |
s->Add(p, wxSizerFlags(1).Expand()); | |
f->SetSizer(s); | |
f->SetClientSize(f->FromDIP(wxSize(800, 600))); | |
f->Show(); | |
return true; | |
} | |
}; | |
wxIMPLEMENT_APP(TestApp); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment