]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/stdrend.cpp
Override GetPixelSize on OS X as the base impl creates a wxScreenDC each time, which...
[wxWidgets.git] / src / univ / stdrend.cpp
index fa8b77dfe03ee1a48b755f15502d13fb1a6970fb..5a78545902b1a7ffb56c8a223811e5e416e8950b 100644 (file)
 #endif
 
 #ifndef WX_PRECOMP
+    #include "wx/settings.h"
+    #include "wx/brush.h"
+    #include "wx/dc.h"
+    #include "wx/statusbr.h"
+    #include "wx/toplevel.h"
 #endif //WX_PRECOMP
 
 #include "wx/univ/stdrend.h"
 #include "wx/univ/colschem.h"
 
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+static const int FRAME_TITLEBAR_HEIGHT             = 18;
+static const int FRAME_BUTTON_WIDTH                = 16;
+static const int FRAME_BUTTON_HEIGHT               = 14;
+
+// the margin between listbox item text and its rectangle
+static const int ITEM_MARGIN = 1;
+
 // ============================================================================
 // wxStdRenderer implementation
 // ============================================================================
@@ -44,6 +60,9 @@ wxStdRenderer::wxStdRenderer(const wxColourScheme *scheme)
     m_penDarkGrey = wxPen(wxSCHEME_COLOUR(scheme, SHADOW_OUT));
     m_penLightGrey = wxPen(wxSCHEME_COLOUR(scheme, SHADOW_IN));
     m_penHighlight = wxPen(wxSCHEME_COLOUR(scheme, SHADOW_HIGHLIGHT));
+
+    m_titlebarFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+    m_titlebarFont.SetWeight(wxFONTWEIGHT_BOLD);
 }
 
 // ----------------------------------------------------------------------------
@@ -89,6 +108,55 @@ void wxStdRenderer::DrawShadedRect(wxDC& dc, wxRect *rect,
     rect->Inflate(-1);
 }
 
+// ----------------------------------------------------------------------------
+// translate various flags into corresponding renderer constants
+// ----------------------------------------------------------------------------
+
+/* static */
+void wxStdRenderer::GetIndicatorsFromFlags(int flags,
+                                           IndicatorState& state,
+                                           IndicatorStatus& status)
+{
+    if ( flags & wxCONTROL_SELECTED )
+        state = flags & wxCONTROL_DISABLED ? IndicatorState_SelectedDisabled
+                                           : IndicatorState_Selected;
+    else if ( flags & wxCONTROL_DISABLED )
+        state = IndicatorState_Disabled;
+    else if ( flags & wxCONTROL_PRESSED )
+        state = IndicatorState_Pressed;
+    else
+        state = IndicatorState_Normal;
+
+    status = flags & wxCONTROL_CHECKED ? IndicatorStatus_Checked
+                                       : flags & wxCONTROL_UNDETERMINED
+                                            ? IndicatorStatus_Undetermined
+                                            : IndicatorStatus_Unchecked;
+}
+
+/* static */
+wxStdRenderer::ArrowDirection wxStdRenderer::GetArrowDirection(wxDirection dir)
+{
+    switch ( dir )
+    {
+        case wxLEFT:
+            return Arrow_Left;
+
+        case wxRIGHT:
+            return Arrow_Right;
+
+        case wxUP:
+            return Arrow_Up;
+
+        case wxDOWN:
+            return Arrow_Down;
+
+        default:
+            wxFAIL_MSG(_T("unknown arrow direction"));
+    }
+
+    return Arrow_Max;
+}
+
 // ----------------------------------------------------------------------------
 // background
 // ----------------------------------------------------------------------------
@@ -99,9 +167,20 @@ void wxStdRenderer::DrawBackground(wxDC& dc,
                                    int WXUNUSED(flags),
                                    wxWindow *window)
 {
-    wxColour colBg = col.Ok() ? col
-                              : window ? m_scheme->GetBackground(window)
-                                       : wxSCHEME_COLOUR(m_scheme, CONTROL);
+    wxColour colBg;
+
+    if (col.Ok())
+    {
+        colBg = col;
+    }
+    else if (window)
+    {
+        colBg = m_scheme->GetBackground(window);
+    }
+    else
+    {
+        colBg = wxSCHEME_COLOUR(m_scheme, CONTROL);
+    }
 
     DrawSolidRect(dc, colBg, rect);
 }
@@ -119,7 +198,8 @@ void wxStdRenderer::DrawButtonSurface(wxDC& dc,
 // text
 // ----------------------------------------------------------------------------
 
-void wxStdRenderer::DrawFocusRect(wxDC& dc, const wxRect& rect)
+void
+wxStdRenderer::DrawFocusRect(wxDC& dc, const wxRect& rect, int WXUNUSED(flags))
 {
     // draw the pixels manually because the "dots" in wxPen with wxDOT style
     // may be short traits and not really dots
@@ -304,6 +384,22 @@ void wxStdRenderer::DrawAntiSunkenBorder(wxDC& dc, wxRect *rect)
     DrawShadedRect(dc, rect, m_penHighlight, m_penDarkGrey);
 }
 
+void wxStdRenderer::DrawBoxBorder(wxDC& dc, wxRect *rect)
+{
+    DrawShadedRect(dc, rect, m_penDarkGrey, m_penHighlight);
+    DrawShadedRect(dc, rect, m_penHighlight, m_penDarkGrey);
+}
+
+void wxStdRenderer::DrawStaticBorder(wxDC& dc, wxRect *rect)
+{
+    DrawShadedRect(dc, rect, m_penDarkGrey, m_penHighlight);
+}
+
+void wxStdRenderer::DrawExtraBorder(wxDC& dc, wxRect *rect)
+{
+    DrawRect(dc, rect, m_penLightGrey);
+}
+
 void wxStdRenderer::DrawBorder(wxDC& dc,
                                wxBorder border,
                                const wxRect& rectTotal,
@@ -320,11 +416,11 @@ void wxStdRenderer::DrawBorder(wxDC& dc,
 
         case wxBORDER_DOUBLE:
             DrawAntiSunkenBorder(dc, &rect);
-            DrawRect(dc, &rect, m_penLightGrey);
+            DrawExtraBorder(dc, &rect);
             break;
 
         case wxBORDER_STATIC:
-            DrawShadedRect(dc, &rect, m_penDarkGrey, m_penHighlight);
+            DrawStaticBorder(dc, &rect);
             break;
 
         case wxBORDER_RAISED:
@@ -386,11 +482,24 @@ wxRect wxStdRenderer::GetBorderDimensions(wxBorder border) const
     return rect;
 }
 
+void wxStdRenderer::AdjustSize(wxSize *size, const wxWindow *window)
+{
+    // take into account the border width
+    wxRect rectBorder = GetBorderDimensions(window->GetBorder());
+    size->x += rectBorder.x + rectBorder.width;
+    size->y += rectBorder.y + rectBorder.height;
+}
+
 bool wxStdRenderer::AreScrollbarsInsideBorder() const
 {
     return false;
 }
 
+wxCoord wxStdRenderer::GetListboxItemHeight(wxCoord fontHeight)
+{
+    return fontHeight + 2*ITEM_MARGIN;
+}
+
 void wxStdRenderer::DrawTextBorder(wxDC& dc,
                                    wxBorder border,
                                    const wxRect& rect,
@@ -493,9 +602,7 @@ void wxStdRenderer::DrawFrame(wxDC& dc,
     }
     else // no label
     {
-        // just draw the complete frame
-        DrawShadedRect(dc, &rectFrame, m_penDarkGrey, m_penHighlight);
-        DrawShadedRect(dc, &rectFrame, m_penHighlight, m_penDarkGrey);
+        DrawBoxBorder(dc, &rectFrame);
     }
 }
 
@@ -516,42 +623,46 @@ void wxStdRenderer::DrawItem(wxDC& dc,
         dc.DrawRectangle(rect);
     }
 
+    // horizontal adjustment is arbitrary
     wxRect rectText = rect;
-    rectText.x += 2;
-    rectText.width -= 2;
+    rectText.Deflate(2, ITEM_MARGIN);
     dc.DrawLabel(label, wxNullBitmap, rectText);
 
     if ( flags & wxCONTROL_FOCUSED )
     {
-        DrawFocusRect(dc, rect);
+        DrawFocusRect(dc, rect, flags);
     }
 }
 
-// ----------------------------------------------------------------------------
-// check and radio bitmaps
-// ----------------------------------------------------------------------------
+void wxStdRenderer::DrawCheckItemBitmap(wxDC& dc,
+                                        const wxBitmap& bitmap,
+                                        const wxRect& rect,
+                                        int flags)
+{
+    DrawCheckButton(dc, wxEmptyString, bitmap, rect, flags);
+}
 
-/* static */
-void wxStdRenderer::GetIndicatorsFromFlags(int flags,
-                                           IndicatorState& state,
-                                           IndicatorStatus& status)
+void wxStdRenderer::DrawCheckItem(wxDC& dc,
+                                  const wxString& label,
+                                  const wxBitmap& bitmap,
+                                  const wxRect& rect,
+                                  int flags)
 {
-    if ( flags & wxCONTROL_SELECTED )
-        state = flags & wxCONTROL_DISABLED ? IndicatorState_SelectedDisabled
-                                           : IndicatorState_Selected;
-    else if ( flags & wxCONTROL_DISABLED )
-        state = IndicatorState_Disabled;
-    else if ( flags & wxCONTROL_PRESSED )
-        state = IndicatorState_Pressed;
-    else
-        state = IndicatorState_Normal;
+    wxRect rectBitmap = rect;
+    rectBitmap.width = GetCheckBitmapSize().x;
+    DrawCheckItemBitmap(dc, bitmap, rectBitmap, flags);
 
-    status = flags & wxCONTROL_CHECKED ? IndicatorStatus_Checked
-                                       : flags & wxCONTROL_UNDETERMINED
-                                            ? IndicatorStatus_Undetermined
-                                            : IndicatorStatus_Unchecked;
+    wxRect rectLabel = rect;
+    wxCoord shift = rectBitmap.width + 2*GetCheckItemMargin();
+    rectLabel.x += shift;
+    rectLabel.width -= shift;
+    DrawItem(dc, label, rectLabel, flags);
 }
 
+// ----------------------------------------------------------------------------
+// check and radio bitmaps
+// ----------------------------------------------------------------------------
+
 void wxStdRenderer::DrawCheckButton(wxDC& dc,
                                     const wxString& label,
                                     const wxBitmap& bitmap,
@@ -681,8 +792,51 @@ void wxStdRenderer::DrawLineWrapMark(wxDC& WXUNUSED(dc),
     // nothing by default
 }
 
+int wxStdRenderer::GetTextBorderWidth(const wxTextCtrl * WXUNUSED(text)) const
+{
+    return 1;
+}
+
+wxRect
+wxStdRenderer::GetTextTotalArea(const wxTextCtrl *text, const wxRect& rect) const
+{
+    wxRect rectTotal = rect;
+    rectTotal.Inflate(GetTextBorderWidth(text));
+    return rectTotal;
+}
+
+wxRect wxStdRenderer::GetTextClientArea(const wxTextCtrl *text,
+                                        const wxRect& rect,
+                                        wxCoord *extraSpaceBeyond) const
+{
+    wxRect rectText = rect;
+    rectText.Deflate(GetTextBorderWidth(text));
+
+    if ( extraSpaceBeyond )
+        *extraSpaceBeyond = 0;
+
+    return rectText;
+}
+
 #endif // wxUSE_TEXTCTRL
 
+// ----------------------------------------------------------------------------
+// scrollbars drawing
+// ----------------------------------------------------------------------------
+
+void wxStdRenderer::DrawScrollbarArrow(wxDC& dc,
+                                       wxDirection dir,
+                                       const wxRect& rect,
+                                       int flags)
+{
+    DrawArrow(dc, dir, rect, flags);
+}
+
+void wxStdRenderer::DrawScrollCorner(wxDC& dc, const wxRect& rect)
+{
+    DrawSolidRect(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), rect);
+}
+
 // ----------------------------------------------------------------------------
 // scrollbars geometry
 // ----------------------------------------------------------------------------
@@ -947,3 +1101,423 @@ int wxStdRenderer::PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord)
 
 #endif // wxUSE_SCROLLBAR
 
+// ----------------------------------------------------------------------------
+// status bar
+// ----------------------------------------------------------------------------
+
+#if wxUSE_STATUSBAR
+
+wxSize wxStdRenderer::GetStatusBarBorders() const
+{
+    // Rendered border may be different depending on field's style, we use
+    // the largest value so that any field certainly fits into the borders
+    // we return:
+    wxRect raised = GetBorderDimensions(wxBORDER_RAISED);
+    wxRect flat = GetBorderDimensions(wxBORDER_STATIC);
+    wxASSERT_MSG( raised.x == raised.width && raised.y == raised.height &&
+                  flat.x == flat.width && flat.y == flat.height,
+                  _T("this code expects uniform borders, you must override GetStatusBarBorders") );
+
+    // take the larger of flat/raised values:
+    wxSize border(wxMax(raised.x, flat.x), wxMax(raised.y, flat.y));
+
+    return border;
+}
+
+wxCoord wxStdRenderer::GetStatusBarBorderBetweenFields() const
+{
+    return 2;
+}
+
+wxSize wxStdRenderer::GetStatusBarFieldMargins() const
+{
+    return wxSize(2, 2);
+}
+
+void wxStdRenderer::DrawStatusField(wxDC& dc,
+                                    const wxRect& rect,
+                                    const wxString& label,
+                                    int flags,
+                                    int style)
+{
+    wxRect rectIn;
+
+    if ( style == wxSB_RAISED )
+        DrawBorder(dc, wxBORDER_RAISED, rect, flags, &rectIn);
+    else if ( style != wxSB_FLAT )
+        DrawBorder(dc, wxBORDER_STATIC, rect, flags, &rectIn);
+
+    rectIn.Deflate(GetStatusBarFieldMargins());
+
+    wxDCClipper clipper(dc, rectIn);
+    DrawLabel(dc, label, rectIn, flags, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
+}
+
+#endif // wxUSE_STATUSBAR
+
+// ----------------------------------------------------------------------------
+// top level windows
+// ----------------------------------------------------------------------------
+
+int wxStdRenderer::HitTestFrame(const wxRect& rect, const wxPoint& pt, int flags) const
+{
+    wxRect client = GetFrameClientArea(rect, flags);
+
+    if ( client.Contains(pt) )
+        return wxHT_TOPLEVEL_CLIENT_AREA;
+
+    if ( flags & wxTOPLEVEL_TITLEBAR )
+    {
+        wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
+
+        if ( flags & wxTOPLEVEL_ICON )
+        {
+            if ( wxRect(client.GetPosition(), GetFrameIconSize()).Contains(pt) )
+                return wxHT_TOPLEVEL_ICON;
+        }
+
+        wxRect btnRect(client.GetRight() - 2 - FRAME_BUTTON_WIDTH,
+                       client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2,
+                       FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT);
+
+        if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
+        {
+            if ( btnRect.Contains(pt) )
+                return wxHT_TOPLEVEL_BUTTON_CLOSE;
+            btnRect.x -= FRAME_BUTTON_WIDTH + 2;
+        }
+        if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
+        {
+            if ( btnRect.Contains(pt) )
+                return wxHT_TOPLEVEL_BUTTON_MAXIMIZE;
+            btnRect.x -= FRAME_BUTTON_WIDTH;
+        }
+        if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
+        {
+            if ( btnRect.Contains(pt) )
+                return wxHT_TOPLEVEL_BUTTON_RESTORE;
+            btnRect.x -= FRAME_BUTTON_WIDTH;
+        }
+        if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
+        {
+            if ( btnRect.Contains(pt) )
+                return wxHT_TOPLEVEL_BUTTON_ICONIZE;
+            btnRect.x -= FRAME_BUTTON_WIDTH;
+        }
+        if ( flags & wxTOPLEVEL_BUTTON_HELP )
+        {
+            if ( btnRect.Contains(pt) )
+                return wxHT_TOPLEVEL_BUTTON_HELP;
+            btnRect.x -= FRAME_BUTTON_WIDTH;
+        }
+
+        if ( pt.y >= client.y && pt.y < client.y + FRAME_TITLEBAR_HEIGHT )
+            return wxHT_TOPLEVEL_TITLEBAR;
+    }
+
+    if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
+    {
+        // we are certainly at one of borders, let's decide which one:
+
+        int border = 0;
+        // dirty trick, relies on the way wxHT_TOPLEVEL_XXX are defined!
+        if ( pt.x < client.x )
+            border |= wxHT_TOPLEVEL_BORDER_W;
+        else if ( pt.x >= client.width + client.x )
+            border |= wxHT_TOPLEVEL_BORDER_E;
+        if ( pt.y < client.y )
+            border |= wxHT_TOPLEVEL_BORDER_N;
+        else if ( pt.y >= client.height + client.y )
+            border |= wxHT_TOPLEVEL_BORDER_S;
+        return border;
+    }
+
+    return wxHT_NOWHERE;
+}
+
+void wxStdRenderer::DrawFrameTitleBar(wxDC& dc,
+                                      const wxRect& rect,
+                                      const wxString& title,
+                                      const wxIcon& icon,
+                                      int flags,
+                                      int specialButton,
+                                      int specialButtonFlags)
+{
+    if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
+    {
+        DrawFrameBorder(dc, rect, flags);
+    }
+    if ( flags & wxTOPLEVEL_TITLEBAR )
+    {
+        DrawFrameBackground(dc, rect, flags);
+        if ( flags & wxTOPLEVEL_ICON )
+            DrawFrameIcon(dc, rect, icon, flags);
+        DrawFrameTitle(dc, rect, title, flags);
+
+        wxRect client = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
+        wxCoord x,y;
+        x = client.GetRight() - 2 - FRAME_BUTTON_WIDTH;
+        y = client.GetTop() + (FRAME_TITLEBAR_HEIGHT-FRAME_BUTTON_HEIGHT)/2;
+
+        if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
+        {
+            DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_CLOSE,
+                            (specialButton == wxTOPLEVEL_BUTTON_CLOSE) ?
+                            specialButtonFlags : 0);
+            x -= FRAME_BUTTON_WIDTH + 2;
+        }
+        if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
+        {
+            DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_MAXIMIZE,
+                            (specialButton == wxTOPLEVEL_BUTTON_MAXIMIZE) ?
+                            specialButtonFlags : 0);
+            x -= FRAME_BUTTON_WIDTH;
+        }
+        if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
+        {
+            DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_RESTORE,
+                            (specialButton == wxTOPLEVEL_BUTTON_RESTORE) ?
+                            specialButtonFlags : 0);
+            x -= FRAME_BUTTON_WIDTH;
+        }
+        if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
+        {
+            DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_ICONIZE,
+                            (specialButton == wxTOPLEVEL_BUTTON_ICONIZE) ?
+                            specialButtonFlags : 0);
+            x -= FRAME_BUTTON_WIDTH;
+        }
+        if ( flags & wxTOPLEVEL_BUTTON_HELP )
+        {
+            DrawFrameButton(dc, x, y, wxTOPLEVEL_BUTTON_HELP,
+                            (specialButton == wxTOPLEVEL_BUTTON_HELP) ?
+                            specialButtonFlags : 0);
+        }
+    }
+}
+
+void wxStdRenderer::DrawFrameBorder(wxDC& dc, const wxRect& rect, int flags)
+{
+    if ( !(flags & wxTOPLEVEL_BORDER) )
+        return;
+
+    wxRect r(rect);
+
+    DrawAntiSunkenBorder(dc, &r);
+    DrawExtraBorder(dc, &r);
+    if ( flags & wxTOPLEVEL_RESIZEABLE )
+        DrawExtraBorder(dc, &r);
+}
+
+void wxStdRenderer::DrawFrameBackground(wxDC& dc, const wxRect& rect, int flags)
+{
+    if ( !(flags & wxTOPLEVEL_TITLEBAR) )
+        return;
+
+    wxColour col = m_scheme->Get(flags & wxTOPLEVEL_ACTIVE
+                                    ? wxColourScheme::TITLEBAR_ACTIVE
+                                    : wxColourScheme::TITLEBAR);
+
+    wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
+    r.height = FRAME_TITLEBAR_HEIGHT;
+
+    DrawBackground(dc, col, r);
+}
+
+void wxStdRenderer::DrawFrameTitle(wxDC& dc,
+                                   const wxRect& rect,
+                                   const wxString& title,
+                                   int flags)
+{
+    wxColour col = m_scheme->Get(flags & wxTOPLEVEL_ACTIVE
+                                    ? wxColourScheme::TITLEBAR_ACTIVE_TEXT
+                                    : wxColourScheme::TITLEBAR_TEXT);
+    dc.SetTextForeground(col);
+
+    wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
+    r.height = FRAME_TITLEBAR_HEIGHT;
+    if ( flags & wxTOPLEVEL_ICON )
+    {
+        r.x += FRAME_TITLEBAR_HEIGHT;
+        r.width -= FRAME_TITLEBAR_HEIGHT + 2;
+    }
+    else
+    {
+        r.x += 1;
+        r.width -= 3;
+    }
+
+    if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
+        r.width -= FRAME_BUTTON_WIDTH + 2;
+    if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
+        r.width -= FRAME_BUTTON_WIDTH;
+    if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
+        r.width -= FRAME_BUTTON_WIDTH;
+    if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
+        r.width -= FRAME_BUTTON_WIDTH;
+    if ( flags & wxTOPLEVEL_BUTTON_HELP )
+        r.width -= FRAME_BUTTON_WIDTH;
+
+    dc.SetFont(m_titlebarFont);
+
+    wxString s;
+    wxCoord textW;
+    dc.GetTextExtent(title, &textW, NULL);
+    if ( textW > r.width )
+    {
+        // text is too big, let's shorten it and add "..." after it:
+        size_t len = title.length();
+        wxCoord WSoFar, letterW;
+
+        dc.GetTextExtent(wxT("..."), &WSoFar, NULL);
+        if ( WSoFar > r.width )
+        {
+            // not enough space to draw anything
+            return;
+        }
+
+        s.Alloc(len);
+        for (size_t i = 0; i < len; i++)
+        {
+            dc.GetTextExtent(title[i], &letterW, NULL);
+            if ( letterW + WSoFar > r.width )
+                break;
+            WSoFar += letterW;
+            s << title[i];
+        }
+        s << wxT("...");
+    }
+    else // no need to truncate the title
+    {
+        s = title;
+    }
+
+    dc.DrawLabel(s, wxNullBitmap, r, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
+}
+
+void wxStdRenderer::DrawFrameIcon(wxDC& dc,
+                                  const wxRect& rect,
+                                  const wxIcon& icon,
+                                  int flags)
+{
+    if ( icon.Ok() )
+    {
+        wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
+        dc.DrawIcon(icon, r.x, r.y);
+    }
+}
+
+void wxStdRenderer::DrawFrameButton(wxDC& dc,
+                                    wxCoord x, wxCoord y,
+                                    int button,
+                                    int flags)
+{
+    FrameButtonType idx;
+    switch (button)
+    {
+        case wxTOPLEVEL_BUTTON_CLOSE:    idx = FrameButton_Close; break;
+        case wxTOPLEVEL_BUTTON_MAXIMIZE: idx = FrameButton_Maximize; break;
+        case wxTOPLEVEL_BUTTON_ICONIZE:  idx = FrameButton_Minimize; break;
+        case wxTOPLEVEL_BUTTON_RESTORE:  idx = FrameButton_Restore; break;
+        case wxTOPLEVEL_BUTTON_HELP:     idx = FrameButton_Help; break;
+        default:
+            wxFAIL_MSG(wxT("incorrect button specification"));
+            return;
+    }
+
+    wxBitmap bmp = GetFrameButtonBitmap(idx);
+    if ( !bmp.Ok() )
+        return;
+
+    wxRect rectBtn(x, y, FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT);
+    if ( flags & wxCONTROL_PRESSED )
+    {
+        DrawSunkenBorder(dc, &rectBtn);
+
+        rectBtn.Offset(1, 1);
+    }
+    else
+    {
+        DrawRaisedBorder(dc, &rectBtn);
+    }
+
+    DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), rectBtn);
+
+    wxRect rectBmp(0, 0, bmp.GetWidth(), bmp.GetHeight());
+    dc.DrawBitmap(bmp, rectBmp.CentreIn(rectBtn).GetPosition(), true);
+}
+
+int wxStdRenderer::GetFrameBorderWidth(int flags) const
+{
+    return flags & wxTOPLEVEL_RESIZEABLE ? 4 : 3;
+}
+
+
+wxRect wxStdRenderer::GetFrameClientArea(const wxRect& rect, int flags) const
+{
+    wxRect r(rect);
+
+    if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
+    {
+        r.Inflate(-GetFrameBorderWidth(flags));
+    }
+
+    if ( flags & wxTOPLEVEL_TITLEBAR )
+    {
+        r.y += FRAME_TITLEBAR_HEIGHT;
+        r.height -= FRAME_TITLEBAR_HEIGHT;
+    }
+
+    return r;
+}
+
+wxSize
+wxStdRenderer::GetFrameTotalSize(const wxSize& clientSize, int flags) const
+{
+    wxSize s(clientSize);
+
+    if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
+    {
+        s.IncBy(2*GetFrameBorderWidth(flags));
+    }
+
+    if ( flags & wxTOPLEVEL_TITLEBAR )
+        s.y += FRAME_TITLEBAR_HEIGHT;
+
+    return s;
+}
+
+wxSize wxStdRenderer::GetFrameMinSize(int flags) const
+{
+    wxSize s;
+
+    if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
+    {
+        s.IncBy(2*GetFrameBorderWidth(flags));
+    }
+
+    if ( flags & wxTOPLEVEL_TITLEBAR )
+    {
+        s.y += FRAME_TITLEBAR_HEIGHT;
+
+        if ( flags & wxTOPLEVEL_ICON )
+            s.x += FRAME_TITLEBAR_HEIGHT + 2;
+        if ( flags & wxTOPLEVEL_BUTTON_CLOSE )
+            s.x += FRAME_BUTTON_WIDTH + 2;
+        if ( flags & wxTOPLEVEL_BUTTON_MAXIMIZE )
+            s.x += FRAME_BUTTON_WIDTH;
+        if ( flags & wxTOPLEVEL_BUTTON_RESTORE )
+            s.x += FRAME_BUTTON_WIDTH;
+        if ( flags & wxTOPLEVEL_BUTTON_ICONIZE )
+            s.x += FRAME_BUTTON_WIDTH;
+        if ( flags & wxTOPLEVEL_BUTTON_HELP )
+            s.x += FRAME_BUTTON_WIDTH;
+    }
+
+    return s;
+}
+
+wxSize wxStdRenderer::GetFrameIconSize() const
+{
+    return wxSize(16, 16);
+}