X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/249803fbcd1f73040e4b5457e341d8db2e5cb66e..2ff0354a3a81557f70a8811a63769b6a42fa4084:/src/univ/stdrend.cpp diff --git a/src/univ/stdrend.cpp b/src/univ/stdrend.cpp index d184d76214..0159f76d77 100644 --- a/src/univ/stdrend.cpp +++ b/src/univ/stdrend.cpp @@ -24,6 +24,11 @@ #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" @@ -33,12 +38,13 @@ // 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 // ============================================================================ @@ -161,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); } @@ -181,7 +198,8 @@ void wxStdRenderer::DrawButtonSurface(wxDC& dc, // 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 @@ -239,6 +257,8 @@ void wxStdRenderer::DrawButtonLabel(wxDC& dc, int indexAccel, wxRect *rectBounds) { + wxDCTextColourChanger clrChanger(dc); + wxRect rectLabel = rect; if ( !label.empty() && (flags & wxCONTROL_DISABLED) ) { @@ -249,13 +269,13 @@ void wxStdRenderer::DrawButtonLabel(wxDC& dc, } // 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 ) { @@ -270,7 +290,7 @@ void wxStdRenderer::DrawButtonLabel(wxDC& dc, { rectLabel.Inflate(-1); - DrawFocusRect(dc, rectLabel); + DrawFocusRect(NULL, dc, rectLabel); } } @@ -366,12 +386,22 @@ void wxStdRenderer::DrawAntiSunkenBorder(wxDC& dc, wxRect *rect) 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, @@ -383,16 +413,20 @@ void wxStdRenderer::DrawBorder(wxDC& dc, 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: @@ -428,13 +462,14 @@ wxRect wxStdRenderer::GetBorderDimensions(wxBorder border) const 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")); // fall through @@ -469,7 +504,7 @@ bool wxStdRenderer::AreScrollbarsInsideBorder() const wxCoord wxStdRenderer::GetListboxItemHeight(wxCoord fontHeight) { - return fontHeight + 2; + return fontHeight + 2*ITEM_MARGIN; } void wxStdRenderer::DrawTextBorder(wxDC& dc, @@ -574,7 +609,7 @@ void wxStdRenderer::DrawFrame(wxDC& dc, } else // no label { - DrawFrameBorder(dc, &rectFrame); + DrawBoxBorder(dc, &rectFrame); } } @@ -595,14 +630,14 @@ 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(NULL, dc, rect, flags); } } @@ -643,9 +678,10 @@ void wxStdRenderer::DrawCheckButton(wxDC& dc, wxAlignment align, int indexAccel) { - wxBitmap bmp(bitmap.Ok() ? bitmap : GetCheckBitmap(flags)); - - DrawCheckOrRadioButton(dc, label, bmp, rect, flags, align, indexAccel); + if (bitmap.Ok()) + DrawCheckOrRadioButton(dc, label, bitmap, rect, flags, align, indexAccel); + else + DrawCheckOrRadioButton(dc, label, GetCheckBitmap(flags), rect, flags, align, indexAccel); } void wxStdRenderer::DrawRadioButton(wxDC& dc, @@ -656,9 +692,11 @@ void wxStdRenderer::DrawRadioButton(wxDC& dc, wxAlignment align, int indexAccel) { - wxBitmap bmp(bitmap.Ok() ? bitmap : GetRadioBitmap(flags)); + if (bitmap.Ok()) + 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, @@ -810,280 +848,35 @@ void wxStdRenderer::DrawScrollCorner(wxDC& dc, const wxRect& rect) } // ---------------------------------------------------------------------------- -// 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, + _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; } -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); } @@ -1100,7 +893,7 @@ void wxStdRenderer::DrawStatusField(wxDC& dc, else if ( style != wxSB_FLAT ) DrawBorder(dc, wxBORDER_STATIC, rect, flags, &rectIn); - rectIn.Deflate(GetStatusBarBorders(NULL)); + rectIn.Deflate(GetStatusBarFieldMargins()); wxDCClipper clipper(dc, rectIn); DrawLabel(dc, label, rectIn, flags, wxALIGN_LEFT | wxALIGN_CENTRE_VERTICAL); @@ -1256,11 +1049,10 @@ void wxStdRenderer::DrawFrameBorder(wxDC& dc, const wxRect& rect, int flags) 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) @@ -1383,22 +1175,27 @@ void wxStdRenderer::DrawFrameButton(wxDC& dc, if ( !bmp.Ok() ) return; - wxRect r(x, y, FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT); + wxRect rectBtn(x, y, FRAME_BUTTON_WIDTH, FRAME_BUTTON_HEIGHT); if ( flags & wxCONTROL_PRESSED ) { - DrawSunkenBorder(dc, &r); + DrawSunkenBorder(dc, &rectBtn); - r.x++; - r.y++; + rectBtn.Offset(1, 1); } else { - DrawRaisedBorder(dc, &r); + DrawRaisedBorder(dc, &rectBtn); } - DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), r); + DrawBackground(dc, wxSCHEME_COLOUR(m_scheme, CONTROL), rectBtn); - dc.DrawBitmap(bmp, r.x, r.y, true); + 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; } @@ -1408,10 +1205,7 @@ 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 ) @@ -1430,11 +1224,7 @@ wxStdRenderer::GetFrameTotalSize(const wxSize& clientSize, int flags) const 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 ) @@ -1449,11 +1239,7 @@ wxSize wxStdRenderer::GetFrameMinSize(int flags) const 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 ) @@ -1481,4 +1267,3 @@ wxSize wxStdRenderer::GetFrameIconSize() const { return wxSize(16, 16); } -