// Purpose: implementation of wxStdRenderer
// Author: Vadim Zeitlin
// Created: 2006-09-16
-// RCS-ID: $Id$
// Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwindows.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#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"
// constants
// ----------------------------------------------------------------------------
-static const int FRAME_BORDER_THICKNESS = 3;
-static const int RESIZEABLE_FRAME_BORDER_THICKNESS = 4;
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
// ============================================================================
return Arrow_Down;
default:
- wxFAIL_MSG(_T("unknown arrow direction"));
+ wxFAIL_MSG(wxT("unknown arrow direction"));
}
return Arrow_Max;
int WXUNUSED(flags),
wxWindow *window)
{
- wxColour colBg = col.Ok() ? col
- : window ? m_scheme->GetBackground(window)
- : wxSCHEME_COLOUR(m_scheme, CONTROL);
+ wxColour colBg;
+
+ if (col.IsOk())
+ {
+ colBg = col;
+ }
+ else if (window)
+ {
+ colBg = m_scheme->GetBackground(window);
+ }
+ else
+ {
+ colBg = wxSCHEME_COLOUR(m_scheme, CONTROL);
+ }
DrawSolidRect(dc, colBg, rect);
}
// text
// ----------------------------------------------------------------------------
-void wxStdRenderer::DrawFocusRect(wxDC& dc, const wxRect& rect)
+void
+wxStdRenderer::DrawFocusRect(wxWindow* WXUNUSED(win), 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
int indexAccel,
wxRect *rectBounds)
{
+ wxDCTextColourChanger clrChanger(dc);
+
wxRect rectLabel = rect;
if ( !label.empty() && (flags & wxCONTROL_DISABLED) )
{
}
// draw shadow of the text
- dc.SetTextForeground(m_penHighlight.GetColour());
+ clrChanger.Set(m_penHighlight.GetColour());
wxRect rectShadow = rect;
rectShadow.Offset(1, 1);
dc.DrawLabel(label, rectShadow, alignment, indexAccel);
// make the main label text grey
- dc.SetTextForeground(m_penDarkGrey.GetColour());
+ clrChanger.Set(m_penDarkGrey.GetColour());
if ( flags & wxCONTROL_FOCUSED )
{
{
rectLabel.Inflate(-1);
- DrawFocusRect(dc, rectLabel);
+ DrawFocusRect(NULL, dc, rectLabel);
}
}
DrawShadedRect(dc, rect, m_penHighlight, m_penDarkGrey);
}
-void wxStdRenderer::DrawFrameBorder(wxDC& dc, wxRect *rect)
+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,
switch ( border )
{
case wxBORDER_SUNKEN:
+ case wxBORDER_THEME:
DrawSunkenBorder(dc, &rect);
break;
+ // wxBORDER_DOUBLE and wxBORDER_THEME are currently the same value.
+#if 0
case wxBORDER_DOUBLE:
DrawAntiSunkenBorder(dc, &rect);
- DrawRect(dc, &rect, m_penLightGrey);
+ DrawExtraBorder(dc, &rect);
break;
+#endif
case wxBORDER_STATIC:
- DrawShadedRect(dc, &rect, m_penDarkGrey, m_penHighlight);
+ DrawStaticBorder(dc, &rect);
break;
case wxBORDER_RAISED:
break;
default:
- wxFAIL_MSG(_T("unknown border type"));
+ wxFAIL_MSG(wxT("unknown border type"));
// fall through
case wxBORDER_DEFAULT:
case wxBORDER_RAISED:
case wxBORDER_SUNKEN:
+ case wxBORDER_THEME:
width = 2;
break;
-
+#if 0
case wxBORDER_DOUBLE:
width = 3;
break;
-
+#endif
default:
- wxFAIL_MSG(_T("unknown border type"));
+ wxFAIL_MSG(wxT("unknown border type"));
// fall through
case wxBORDER_DEFAULT:
wxCoord wxStdRenderer::GetListboxItemHeight(wxCoord fontHeight)
{
- return fontHeight + 2;
+ return fontHeight + 2*ITEM_MARGIN;
}
void wxStdRenderer::DrawTextBorder(wxDC& dc,
}
else // no label
{
- DrawFrameBorder(dc, &rectFrame);
+ DrawBoxBorder(dc, &rectFrame);
}
}
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(NULL, dc, rect, flags);
}
}
wxAlignment align,
int indexAccel)
{
- wxBitmap bmp(bitmap.Ok() ? bitmap : GetCheckBitmap(flags));
-
- DrawCheckOrRadioButton(dc, label, bmp, rect, flags, align, indexAccel);
+ if (bitmap.IsOk())
+ DrawCheckOrRadioButton(dc, label, bitmap, rect, flags, align, indexAccel);
+ else
+ DrawCheckOrRadioButton(dc, label, GetCheckBitmap(flags), rect, flags, align, indexAccel);
}
void wxStdRenderer::DrawRadioButton(wxDC& dc,
wxAlignment align,
int indexAccel)
{
- wxBitmap bmp(bitmap.Ok() ? bitmap : GetRadioBitmap(flags));
+ if (bitmap.IsOk())
+ DrawCheckOrRadioButton(dc, label, bitmap, rect, flags, align, indexAccel);
+ else
+ DrawCheckOrRadioButton(dc, label, GetRadioBitmap(flags), rect, flags, align, indexAccel);
- DrawCheckOrRadioButton(dc, label, bmp, rect, flags, align, indexAccel);
}
void wxStdRenderer::DrawCheckOrRadioButton(wxDC& dc,
}
// ----------------------------------------------------------------------------
-// scrollbars geometry
+// status bar
// ----------------------------------------------------------------------------
-#if wxUSE_SCROLLBAR
-
-/* static */
-void wxStdRenderer::GetScrollBarThumbSize(wxCoord length,
- int thumbPos,
- int thumbSize,
- int range,
- wxCoord *thumbStart,
- wxCoord *thumbEnd)
-{
- // the thumb can't be made less than this number of pixels
- static const wxCoord thumbMinWidth = 8; // FIXME: should be configurable
-
- *thumbStart = (length*thumbPos) / range;
- *thumbEnd = (length*(thumbPos + thumbSize)) / range;
-
- if ( *thumbEnd - *thumbStart < thumbMinWidth )
- {
- // adjust the end if possible
- if ( *thumbStart <= length - thumbMinWidth )
- {
- // yes, just make it wider
- *thumbEnd = *thumbStart + thumbMinWidth;
- }
- else // it is at the bottom of the scrollbar
- {
- // so move it a bit up
- *thumbStart = length - thumbMinWidth;
- *thumbEnd = length;
- }
- }
-}
-
-wxRect wxStdRenderer::GetScrollbarRect(const wxScrollBar *scrollbar,
- wxScrollBar::Element elem,
- int thumbPos) const
-{
- if ( thumbPos == -1 )
- {
- thumbPos = scrollbar->GetThumbPosition();
- }
-
- const wxSize sizeArrow = GetScrollbarArrowSize();
-
- wxSize sizeTotal = scrollbar->GetClientSize();
- wxCoord *start, *width;
- wxCoord length, arrow;
- wxRect rect;
- if ( scrollbar->IsVertical() )
- {
- rect.x = 0;
- rect.width = sizeTotal.x;
- length = sizeTotal.y;
- start = &rect.y;
- width = &rect.height;
- arrow = sizeArrow.y;
- }
- else // horizontal
- {
- rect.y = 0;
- rect.height = sizeTotal.y;
- length = sizeTotal.x;
- start = &rect.x;
- width = &rect.width;
- arrow = sizeArrow.x;
- }
-
- switch ( elem )
- {
- case wxScrollBar::Element_Arrow_Line_1:
- *start = 0;
- *width = arrow;
- break;
-
- case wxScrollBar::Element_Arrow_Line_2:
- *start = length - arrow;
- *width = arrow;
- break;
-
- case wxScrollBar::Element_Arrow_Page_1:
- case wxScrollBar::Element_Arrow_Page_2:
- // we don't have them at all
- break;
-
- case wxScrollBar::Element_Thumb:
- case wxScrollBar::Element_Bar_1:
- case wxScrollBar::Element_Bar_2:
- // we need to calculate the thumb position - do it
- {
- length -= 2*arrow;
- wxCoord thumbStart, thumbEnd;
- int range = scrollbar->GetRange();
- if ( !range )
- {
- thumbStart =
- thumbEnd = 0;
- }
- else
- {
- GetScrollBarThumbSize(length,
- thumbPos,
- scrollbar->GetThumbSize(),
- range,
- &thumbStart,
- &thumbEnd);
- }
-
- if ( elem == wxScrollBar::Element_Thumb )
- {
- *start = thumbStart;
- *width = thumbEnd - thumbStart;
- }
- else if ( elem == wxScrollBar::Element_Bar_1 )
- {
- *start = 0;
- *width = thumbStart;
- }
- else // elem == wxScrollBar::Element_Bar_2
- {
- *start = thumbEnd;
- *width = length - thumbEnd;
- }
-
- // everything is relative to the start of the shaft so far
- *start += arrow;
- }
- break;
-
- case wxScrollBar::Element_Max:
- default:
- wxFAIL_MSG( _T("unknown scrollbar element") );
- }
-
- return rect;
-}
-
-wxCoord wxStdRenderer::GetScrollbarSize(const wxScrollBar *scrollbar)
-{
- const wxSize sizeArrowSB = GetScrollbarArrowSize();
-
- wxCoord sizeArrow, sizeTotal;
- if ( scrollbar->GetWindowStyle() & wxVERTICAL )
- {
- sizeArrow = sizeArrowSB.y;
- sizeTotal = scrollbar->GetSize().y;
- }
- else // horizontal
- {
- sizeArrow = sizeArrowSB.x;
- sizeTotal = scrollbar->GetSize().x;
- }
-
- return sizeTotal - 2*sizeArrow;
-}
-
-wxHitTest
-wxStdRenderer::HitTestScrollbar(const wxScrollBar *scrollbar, const wxPoint& pt) const
-{
- // we only need to work with either x or y coord depending on the
- // orientation, choose one (but still check the other one to verify if the
- // mouse is in the window at all)
- const wxSize sizeArrowSB = GetScrollbarArrowSize();
-
- wxCoord coord, sizeArrow, sizeTotal;
- wxSize size = scrollbar->GetSize();
- if ( scrollbar->GetWindowStyle() & wxVERTICAL )
- {
- if ( pt.x < 0 || pt.x > size.x )
- return wxHT_NOWHERE;
-
- coord = pt.y;
- sizeArrow = sizeArrowSB.y;
- sizeTotal = size.y;
- }
- else // horizontal
- {
- if ( pt.y < 0 || pt.y > size.y )
- return wxHT_NOWHERE;
-
- coord = pt.x;
- sizeArrow = sizeArrowSB.x;
- sizeTotal = size.x;
- }
-
- // test for the arrows first as it's faster
- if ( coord < 0 || coord > sizeTotal )
- {
- return wxHT_NOWHERE;
- }
- else if ( coord < sizeArrow )
- {
- return wxHT_SCROLLBAR_ARROW_LINE_1;
- }
- else if ( coord > sizeTotal - sizeArrow )
- {
- return wxHT_SCROLLBAR_ARROW_LINE_2;
- }
- else
- {
- // calculate the thumb position in pixels
- sizeTotal -= 2*sizeArrow;
- wxCoord thumbStart, thumbEnd;
- int range = scrollbar->GetRange();
- if ( !range )
- {
- // clicking the scrollbar without range has no effect
- return wxHT_NOWHERE;
- }
- else
- {
- GetScrollBarThumbSize(sizeTotal,
- scrollbar->GetThumbPosition(),
- scrollbar->GetThumbSize(),
- range,
- &thumbStart,
- &thumbEnd);
- }
-
- // now compare with the thumb position
- coord -= sizeArrow;
- if ( coord < thumbStart )
- return wxHT_SCROLLBAR_BAR_1;
- else if ( coord > thumbEnd )
- return wxHT_SCROLLBAR_BAR_2;
- else
- return wxHT_SCROLLBAR_THUMB;
- }
-}
-
+#if wxUSE_STATUSBAR
-wxCoord
-wxStdRenderer::ScrollbarToPixel(const wxScrollBar *scrollbar, int thumbPos)
+wxSize wxStdRenderer::GetStatusBarBorders() const
{
- int range = scrollbar->GetRange();
- if ( !range )
- {
- // the only valid position anyhow
- return 0;
- }
-
- if ( thumbPos == -1 )
- {
- // by default use the current thumb position
- thumbPos = scrollbar->GetThumbPosition();
- }
-
- const wxSize sizeArrow = GetScrollbarArrowSize();
- return (thumbPos*GetScrollbarSize(scrollbar)) / range
- + (scrollbar->IsVertical() ? sizeArrow.y : sizeArrow.x);
+ // 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,
+ wxT("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;
}
-int wxStdRenderer::PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord)
+wxCoord wxStdRenderer::GetStatusBarBorderBetweenFields() const
{
- const wxSize sizeArrow = GetScrollbarArrowSize();
- return ((coord - (scrollbar->IsVertical() ? sizeArrow.y : sizeArrow.x)) *
- scrollbar->GetRange() ) / GetScrollbarSize(scrollbar);
+ return 2;
}
-#endif // wxUSE_SCROLLBAR
-
-// ----------------------------------------------------------------------------
-// status bar
-// ----------------------------------------------------------------------------
-
-#if wxUSE_STATUSBAR
-
-wxSize wxStdRenderer::GetStatusBarBorders(wxCoord *borderBetweenFields) const
+wxSize wxStdRenderer::GetStatusBarFieldMargins() const
{
- if ( borderBetweenFields )
- *borderBetweenFields = 2;
-
return wxSize(2, 2);
}
DrawBorder(dc, wxBORDER_RAISED, rect, flags, &rectIn);
else if ( style != wxSB_FLAT )
DrawBorder(dc, wxBORDER_STATIC, rect, flags, &rectIn);
+ else
+ rectIn = rect;
- rectIn.Deflate(GetStatusBarBorders(NULL));
+ rectIn.Deflate(GetStatusBarFieldMargins());
wxDCClipper clipper(dc, rectIn);
DrawLabel(dc, label, rectIn, flags, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL);
wxRect r(rect);
- DrawShadedRect(dc, &r, m_penLightGrey, m_penBlack);
- DrawShadedRect(dc, &r, m_penHighlight, m_penDarkGrey);
- DrawShadedRect(dc, &r, m_penLightGrey, m_penLightGrey);
+ DrawAntiSunkenBorder(dc, &r);
+ DrawExtraBorder(dc, &r);
if ( flags & wxTOPLEVEL_RESIZEABLE )
- DrawShadedRect(dc, &r, m_penLightGrey, m_penLightGrey);
+ DrawExtraBorder(dc, &r);
}
void wxStdRenderer::DrawFrameBackground(wxDC& dc, const wxRect& rect, int flags)
const wxIcon& icon,
int flags)
{
- if ( icon.Ok() )
+ if ( icon.IsOk() )
{
wxRect r = GetFrameClientArea(rect, flags & ~wxTOPLEVEL_TITLEBAR);
dc.DrawIcon(icon, r.x, r.y);
}
wxBitmap bmp = GetFrameButtonBitmap(idx);
- if ( !bmp.Ok() )
+ if ( !bmp.IsOk() )
return;
wxRect rectBtn(x, y, FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT);
{
DrawSunkenBorder(dc, &rectBtn);
- rectBtn.x++;
- rectBtn.y++;
+ rectBtn.Offset(1, 1);
}
else
{
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
{
if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
{
- int border = flags & wxTOPLEVEL_RESIZEABLE
- ? RESIZEABLE_FRAME_BORDER_THICKNESS
- : FRAME_BORDER_THICKNESS;
- r.Inflate(-border);
+ r.Inflate(-GetFrameBorderWidth(flags));
}
if ( flags & wxTOPLEVEL_TITLEBAR )
if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
{
- int border = flags & wxTOPLEVEL_RESIZEABLE
- ? RESIZEABLE_FRAME_BORDER_THICKNESS
- : FRAME_BORDER_THICKNESS;
- s.x += 2*border;
- s.y += 2*border;
+ s.IncBy(2*GetFrameBorderWidth(flags));
}
if ( flags & wxTOPLEVEL_TITLEBAR )
if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) )
{
- int border = (flags & wxTOPLEVEL_RESIZEABLE) ?
- RESIZEABLE_FRAME_BORDER_THICKNESS :
- FRAME_BORDER_THICKNESS;
- s.x += 2*border;
- s.y += 2*border;
+ s.IncBy(2*GetFrameBorderWidth(flags));
}
if ( flags & wxTOPLEVEL_TITLEBAR )
{
return wxSize(16, 16);
}
-