X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6229b92fb31d5a82c9ffe3790a85a13def4409f4..85a94ef07bc7b67ce7c418bb672c51a0a54d6f73:/src/univ/stdrend.cpp diff --git a/src/univ/stdrend.cpp b/src/univ/stdrend.cpp index 771b3a9052..d29a4dc89b 100644 --- a/src/univ/stdrend.cpp +++ b/src/univ/stdrend.cpp @@ -24,11 +24,26 @@ #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_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; + // ============================================================================ // wxStdRenderer implementation // ============================================================================ @@ -44,6 +59,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 +107,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 // ---------------------------------------------------------------------------- @@ -304,12 +371,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, @@ -326,11 +403,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: @@ -392,11 +469,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; +} + void wxStdRenderer::DrawTextBorder(wxDC& dc, wxBorder border, const wxRect& rect, @@ -499,7 +589,7 @@ void wxStdRenderer::DrawFrame(wxDC& dc, } else // no label { - DrawFrameBorder(dc, &rectFrame); + DrawBoxBorder(dc, &rectFrame); } } @@ -560,27 +650,6 @@ void wxStdRenderer::DrawCheckItem(wxDC& dc, // check and radio bitmaps // ---------------------------------------------------------------------------- -/* 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; -} - void wxStdRenderer::DrawCheckButton(wxDC& dc, const wxString& label, const wxBitmap& bitmap, @@ -738,6 +807,23 @@ wxRect wxStdRenderer::GetTextClientArea(const wxTextCtrl *text, #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 // ---------------------------------------------------------------------------- @@ -1002,3 +1088,410 @@ int wxStdRenderer::PixelToScrollbar(const wxScrollBar *scrollbar, wxCoord coord) #endif // wxUSE_SCROLLBAR +// ---------------------------------------------------------------------------- +// status bar +// ---------------------------------------------------------------------------- + +#if wxUSE_STATUSBAR + +wxSize wxStdRenderer::GetStatusBarBorders(wxCoord *borderBetweenFields) const +{ + if ( borderBetweenFields ) + *borderBetweenFields = 2; + + 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(GetStatusBarBorders(NULL)); + + 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); +} + + +wxRect wxStdRenderer::GetFrameClientArea(const wxRect& rect, int flags) const +{ + wxRect r(rect); + + if ( (flags & wxTOPLEVEL_BORDER) && !(flags & wxTOPLEVEL_MAXIMIZED) ) + { + int border = flags & wxTOPLEVEL_RESIZEABLE + ? RESIZEABLE_FRAME_BORDER_THICKNESS + : FRAME_BORDER_THICKNESS; + r.Inflate(-border); + } + + 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) ) + { + int border = flags & wxTOPLEVEL_RESIZEABLE + ? RESIZEABLE_FRAME_BORDER_THICKNESS + : FRAME_BORDER_THICKNESS; + s.x += 2*border; + s.y += 2*border; + } + + 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) ) + { + int border = (flags & wxTOPLEVEL_RESIZEABLE) ? + RESIZEABLE_FRAME_BORDER_THICKNESS : + FRAME_BORDER_THICKNESS; + s.x += 2*border; + s.y += 2*border; + } + + 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); +}