ModernDockArt is a custom wxDockArt class, that implements a look similar to Firefox and other recents applications.
Is uses wxRenderer and XP themes whenever possible, so it should look good even if the user has a custom theme.
A future improvement might be to add a DrawSmallCloseButton() function to wxRenderer (in wxWidgets) so that you we don't have to make custom code for each platform. Other controls, like tabbed interfaces and the like would also benefit from this.
You will need the wxDockArt improvements from my previous posting for it to compile.
You are free to use this in any way you like.
- Code: Select all
#include "manager.h"
#include <wx/renderer.h>
#if wxUSE_UXTHEME
#include "wx/msw/uxtheme.h" // XP theme handling
#endif
class ModernDockArt : public wxDefaultDockArt
{
public:
ModernDockArt(wxWindow* win);
void DrawPaneButton(wxDC& dc,
int button,
int button_state,
const wxRect& rect,
wxPaneInfo& pane);
void DrawCaption(wxDC& dc,
const wxString& text,
const wxRect& rect,
wxPaneInfo& pane);
protected:
void DrawCaptionBackground(wxDC& dc, const wxRect& rect, bool active);
private:
wxWindow* m_win;
};
ModernDockArt::ModernDockArt(wxWindow* win) : wxDefaultDockArt(), m_win(win)
{
bool usingTheme = false;
// Get the size of a small close button (themed)
#if wxUSE_UXTHEME
if (wxUxThemeEngine::Get())
{
wxUxThemeHandle hTheme(m_win, L"WINDOW");
if (hTheme)
{
usingTheme = true;
wxClientDC dc(m_win);
HDC hdc = GetHdcOf(dc);
wxSize size(13, 15);
SIZE sz;
wxUxThemeEngine::Get()->GetThemePartSize(hTheme, hdc, 19 /*WP_SMALLCLOSEBUTTON*/,
1 /* CBS_NORMAL */, NULL, TS_TRUE, &sz);
m_button_size = sz.cx;
}
}
#endif // wxUSE_UXTHEME
m_button_border_size = 3;
m_caption_text_indent = 6;
m_caption_size = 22;
// We only highlight the active pane with the caption text being in bold.
// So we do not want a special colour for active elements.
m_active_caption_colour = m_inactive_caption_colour;
m_active_close_bitmap = m_inactive_close_bitmap;
};
void ModernDockArt::DrawCaption(wxDC& dc,
const wxString& text,
const wxRect& rect,
wxPaneInfo& pane)
{
dc.SetPen(*wxTRANSPARENT_PEN);
DrawCaptionBackground(dc, rect,
(pane.state & wxPaneInfo::optionActive)?true:false);
// Active captions are drawn with bold text
if (pane.state & wxPaneInfo::optionActive)
m_caption_font.SetWeight(wxFONTWEIGHT_BOLD);
else
m_caption_font.SetWeight(wxFONTWEIGHT_NORMAL);
dc.SetFont(m_caption_font);
dc.SetTextForeground(m_inactive_caption_text_colour);
wxCoord w,h;
dc.GetTextExtent(wxT("ABCDEFHXfgkj"), &w, &h);
dc.SetClippingRegion(rect);
dc.DrawText(text, rect.x+m_caption_text_indent, rect.y+(rect.height/2)-(h/2)-1);
dc.DestroyClippingRegion();
}
void ModernDockArt::DrawCaptionBackground(wxDC& dc,
const wxRect& rect,
bool active)
{
// Clear the background
dc.SetBrush(m_background_brush);
dc.DrawRectangle(rect.x, rect.y, rect.width, rect.height);
if (active)
{
wxRendererNative::Get().DrawHeaderButton(m_win, dc, rect, wxCONTROL_FOCUSED);
}
else
{
wxRendererNative::Get().DrawHeaderButton(m_win, dc, rect);
}
}
void ModernDockArt::DrawPaneButton(wxDC& dc,int button,
int button_state,
const wxRect& _rect,
wxPaneInfo& pane)
{
bool usingTheme = false;
#if wxUSE_UXTHEME
if (wxUxThemeEngine::Get())
{
wxUxThemeHandle hTheme(m_win, L"WINDOW");
if (hTheme)
{
usingTheme = true;
// Get the real button position (compensating for borders)
const wxRect rect(_rect.x, _rect.y+m_button_border_size, m_button_size, m_button_size);
// Draw the themed close button
RECT rc;
wxCopyRectToRECT(rect, rc);
int state = 0;
switch (button_state) {
case wxAUI_BUTTON_STATE_NORMAL:
state = 1; // CBS_NORMAL
break;
case wxAUI_BUTTON_STATE_HOVER:
state = 2; // CBS_HOT
break;
case wxAUI_BUTTON_STATE_PRESSED:
state = 3; // CBS_PUSHED
break;
default:
wxASSERT_MSG(false, wxT("Unknown state"));
}
wxUxThemeEngine::Get()->DrawThemeBackground(hTheme, GetHdcOf(dc), 19 /*WP_SMALLCLOSEBUTTON*/,
state, &rc, NULL);
}
}
#endif // wxUSE_UXTHEME
// Fallback to default closebutton if themes are not enabled
if (!usingTheme) wxDefaultDockArt::DrawPaneButton(dc, button, button_state, _rect, pane);
}