void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event))
{
    wxPaintDC dc(this);
    wxMemoryDC memdc;
    RECT rc;
    ::GetClientRect(GetHwnd(), &rc);
    wxBitmap bmp(rc.right, rc.bottom);
    memdc.SelectObject(bmp);

    const wxLayoutDirection dir = dc.GetLayoutDirection();
    memdc.SetLayoutDirection(dir);

    const HDC hdc = GetHdcOf(memdc);

    // The drawing logic of the native tab control is absolutely impenetrable
    // but observation shows that in the current Windows versions (XP and 7),
    // the tab control always erases its entire background in its window proc
    // when the tabs are top-aligned but does not do it when the tabs are in
    // any other position.
    //
    // This means that we can't rely on our background colour being used for
    // the blank area in the tab row because this doesn't work in the default
    // top-aligned case, hence the hack with ExtFloodFill() below. But it also
    // means that we still do need to erase the DC to account for the other
    // cases.
    //
    // Moreover, just in case some very old or very new (or even future,
    // although it seems unlikely that this is ever going to change by now)
    // version of Windows didn't do it like this, do both things in all cases
    // instead of optimizing away the one of them which doesn't do anything for
    // the effectively used tab orientation -- better safe than fast.

    // Notice that we use our own background here, not the background used for
    // the pages, because the tab row background must blend with the parent and
    // so the background colour inherited from it (if any) must be used.
    AutoHBRUSH hbr(wxColourToRGB(GetBackgroundColour()));

    ::FillRect(hdc, &rc, hbr);

    MSWDefWindowProc(WM_PAINT, (WPARAM)hdc, 0);

    // At least for the top-aligned tabs, our background colour was overwritten
    // and so we now replace the default background with our colour. This is
    // horribly inefficient, of course, but seems to be the only way to do it.
    if ( UseBgCol() )
    {
        SelectInHDC selectBrush(hdc, hbr);

        // Find the point which must contain the default background colour:
        // this is a hack, of course, but using this point "close" to the
        // corner seems to work fine in practice.
        int x = 0,
            y = 0;

        switch ( GetWindowStyle() & wxBK_ALIGN_MASK )
        {
            case wxBK_TOP:
                x = rc.right - 2;
                y = 2;
                break;

            case wxBK_BOTTOM:
                x = rc.right - 2;
                y = rc.bottom - 2;
                break;

            case wxBK_LEFT:
                x = 2;
                y = rc.bottom - 2;
                break;

            case wxBK_RIGHT:
                x = 2;
                y = rc.bottom - 2;
                break;
        }

        ::ExtFloodFill(hdc, x, y, ::GetSysColor(COLOR_BTNFACE), FLOODFILLSURFACE);
    }

    // For some reason in RTL mode, source offset has to be -1, otherwise the
    // right border (physical) remains unpainted.
    const wxCoord ofs = dir == wxLayout_RightToLeft ? -1 : 0;
    dc.Blit(ofs, 0, rc.right, rc.bottom, &memdc, ofs, 0);
}
Beispiel #2
0
bool wxMenuItem::OnDrawItem(wxDC& dc, const wxRect& rc,
                            wxODAction WXUNUSED(act), wxODStatus stat)
{
    const MenuDrawData* data = MenuDrawData::Get();

    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
    HDC hdc = GetHdcOf(*impl);

    RECT rect;
    wxCopyRectToRECT(rc, rect);

    int imgWidth = wxMax(GetMarginWidth(), data->CheckSize.cx);

    if ( IsOwnerDrawn() )
    {
        // font and colors to use
        wxFont font;
        GetFontToUse(font);

        wxColour colText, colBack;
        GetColourToUse(stat, colText, colBack);

        // calculate metrics of item parts
        RECT rcSelection = rect;
        data->ItemMargin.ApplyTo(rcSelection);

        RECT rcSeparator = rcSelection;
        data->SeparatorMargin.ApplyTo(rcSeparator);

        RECT rcGutter = rcSelection;
        rcGutter.right = data->ItemMargin.cxLeftWidth
                       + data->CheckBgMargin.cxLeftWidth
                       + data->CheckMargin.cxLeftWidth
                       + imgWidth
                       + data->CheckMargin.cxRightWidth
                       + data->CheckBgMargin.cxRightWidth;

        RECT rcText = rcSelection;
        rcText.left = rcGutter.right + data->TextBorder;

        // we draw the text label vertically centered, but this results in it
        // being 1px too low compared to native menus for some reason, fix it
        if ( data->MenuLayout() != MenuDrawData::FullTheme )
            rcText.top--;

#if wxUSE_UXTHEME
        // If a custom background colour is explicitly specified, we should use
        // it instead of the default theme background.
        wxUxThemeEngine* const theme = GetBackgroundColour().IsOk()
                                        ? NULL
                                        : MenuDrawData::GetUxThemeEngine();
        if ( theme )
        {
            POPUPITEMSTATES state;
            if ( stat & wxODDisabled )
            {
                state = (stat & wxODSelected) ? MPI_DISABLEDHOT
                                              : MPI_DISABLED;
            }
            else if ( stat & wxODSelected )
            {
                state = MPI_HOT;
            }
            else
            {
                state = MPI_NORMAL;
            }

            wxUxThemeHandle hTheme(GetMenu()->GetWindow(), L"MENU");

            if ( theme->IsThemeBackgroundPartiallyTransparent(hTheme,
                    MENU_POPUPITEM, state) )
            {
                theme->DrawThemeBackground(hTheme, hdc,
                                           MENU_POPUPBACKGROUND,
                                           0, &rect, NULL);
            }

            theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPGUTTER,
                                       0, &rcGutter, NULL);

            if ( IsSeparator() )
            {
                rcSeparator.left = rcGutter.right;
                theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPSEPARATOR,
                                           0, &rcSeparator, NULL);
                return true;
            }

            theme->DrawThemeBackground(hTheme, hdc, MENU_POPUPITEM,
                                       state, &rcSelection, NULL);

        }
        else
#endif // wxUSE_UXTHEME
        {
            if ( IsSeparator() )
            {
                DrawEdge(hdc, &rcSeparator, EDGE_ETCHED, BF_TOP);
                return true;
            }

            AutoHBRUSH hbr(colBack.GetPixel());
            SelectInHDC selBrush(hdc, hbr);
            ::FillRect(hdc, &rcSelection, hbr);
        }


        // draw text label
        // using native API because it recognizes '&'

        HDCTextColChanger changeTextCol(hdc, colText.GetPixel());
        HDCBgColChanger changeBgCol(hdc, colBack.GetPixel());
        HDCBgModeChanger changeBgMode(hdc, TRANSPARENT);

        SelectInHDC selFont(hdc, GetHfontOf(font));


        // item text name without mnemonic for calculating size
        wxString text = GetName();

        SIZE textSize;
        ::GetTextExtentPoint32(hdc, text.c_str(), text.length(), &textSize);

        // item text name with mnemonic
        text = GetItemLabel().BeforeFirst('\t');

        int flags = DST_PREFIXTEXT;
        // themes menu is using specified color for disabled labels
        if ( data->MenuLayout() == MenuDrawData::Classic &&
             (stat & wxODDisabled) && !(stat & wxODSelected) )
            flags |= DSS_DISABLED;

        if ( (stat & wxODHidePrefix) && !data->AlwaysShowCues )
            flags |= DSS_HIDEPREFIX;

        int x = rcText.left;
        int y = rcText.top + (rcText.bottom - rcText.top - textSize.cy) / 2;

        ::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(text),
                    text.length(), x, y, 0, 0, flags);

        // ::SetTextAlign(hdc, TA_RIGHT) doesn't work with DSS_DISABLED or DSS_MONO
        // as the last parameter in DrawState() (at least with Windows98). So we have
        // to take care of right alignment ourselves.
        wxString accel = GetItemLabel().AfterFirst(wxT('\t'));
        if ( !accel.empty() )
        {
            SIZE accelSize;
            ::GetTextExtentPoint32(hdc, accel.c_str(), accel.length(), &accelSize);

            flags = DST_TEXT;
            // themes menu is using specified color for disabled labels
            if ( data->MenuLayout() == MenuDrawData::Classic &&
                 (stat & wxODDisabled) && !(stat & wxODSelected) )
                flags |= DSS_DISABLED;

            x = rcText.right - data->ArrowMargin.GetTotalX()
                                 - data->ArrowSize.cx
                                 - data->ArrowBorder;

            // right align accel on FullTheme menu, left otherwise
            if ( data->MenuLayout() == MenuDrawData::FullTheme)
                x -= accelSize.cx;
            else
                x -= m_parentMenu->GetMaxAccelWidth();

            y = rcText.top + (rcText.bottom - rcText.top - accelSize.cy) / 2;

            ::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(accel),
                        accel.length(), x, y, 0, 0, flags);
        }
    }


    // draw the bitmap

    RECT rcImg;
    SetRect(&rcImg,
            rect.left   + data->ItemMargin.cxLeftWidth
                        + data->CheckBgMargin.cxLeftWidth
                        + data->CheckMargin.cxLeftWidth,
            rect.top    + data->ItemMargin.cyTopHeight
                        + data->CheckBgMargin.cyTopHeight
                        + data->CheckMargin.cyTopHeight,
            rect.left   + data->ItemMargin.cxLeftWidth
                        + data->CheckBgMargin.cxLeftWidth
                        + data->CheckMargin.cxLeftWidth
                        + imgWidth,
            rect.bottom - data->ItemMargin.cyBottomHeight
                        - data->CheckBgMargin.cyBottomHeight
                        - data->CheckMargin.cyBottomHeight);

    if ( IsCheckable() && !m_bmpChecked.IsOk() )
    {
        if ( stat & wxODChecked )
        {
            DrawStdCheckMark((WXHDC)hdc, &rcImg, stat);
        }
    }
    else
    {
        wxBitmap bmp;

        if ( stat & wxODDisabled )
        {
            bmp = GetDisabledBitmap();
        }

        if ( !bmp.IsOk() )
        {
            // for not checkable bitmaps we should always use unchecked one
            // because their checked bitmap is not set
            bmp = GetBitmap(!IsCheckable() || (stat & wxODChecked));

#if wxUSE_IMAGE
            if ( bmp.IsOk() && stat & wxODDisabled )
            {
                // we need to grey out the bitmap as we don't have any specific
                // disabled bitmap
                wxImage imgGrey = bmp.ConvertToImage().ConvertToGreyscale();
                if ( imgGrey.IsOk() )
                    bmp = wxBitmap(imgGrey);
            }
#endif // wxUSE_IMAGE
        }

        if ( bmp.IsOk() )
        {
            wxMemoryDC dcMem(&dc);
            dcMem.SelectObjectAsSource(bmp);

            // center bitmap
            int nBmpWidth  = bmp.GetWidth(),
                nBmpHeight = bmp.GetHeight();

            int x = rcImg.left + (imgWidth - nBmpWidth) / 2;
            int y = rcImg.top  + (rcImg.bottom - rcImg.top - nBmpHeight) / 2;
            dc.Blit(x, y, nBmpWidth, nBmpHeight, &dcMem, 0, 0, wxCOPY, true);
        }
    }

    return true;

}
Beispiel #3
0
void wxStaticBox::PaintForeground(wxDC& dc, const RECT& rc)
{
    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
    MSWDefWindowProc(WM_PAINT, (WPARAM)GetHdcOf(*impl), 0);

    // when using XP themes, neither setting the text colour nor transparent
    // background mode doesn't change anything: the static box def window proc
    // still draws the label in its own colours, so we need to redraw the text
    // ourselves if we have a non default fg colour
    if ( m_hasFgCol && wxUxThemeEngine::GetIfActive() )
    {
        // draw over the text in default colour in our colour
        HDC hdc = GetHdcOf(*impl);
        ::SetTextColor(hdc, GetForegroundColour().GetPixel());

        const bool rtl = wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft;
        if ( rtl )
            ::SetTextAlign(hdc, TA_RTLREADING | TA_RIGHT);

        // Get dimensions of the label
        const wxString label = GetLabel();

        // choose the correct font
        AutoHFONT font;
        SelectInHDC selFont;
        if ( m_hasFont )
        {
            selFont.Init(hdc, GetHfontOf(GetFont()));
        }
        else // no font set, use the one set by the theme
        {
            wxUxThemeHandle hTheme(this, L"BUTTON");
            if ( hTheme )
            {
                wxUxThemeFont themeFont;
                if ( wxUxThemeEngine::Get()->GetThemeFont
                                             (
                                                hTheme,
                                                hdc,
                                                BP_GROUPBOX,
                                                GBS_NORMAL,
                                                TMT_FONT,
                                                themeFont.GetPtr()
                                             ) == S_OK )
                {
                    font.Init(themeFont.GetLOGFONT());
                    if ( font )
                        selFont.Init(hdc, font);
                }
            }
        }

        // Get the font extent
        int width, height;
        dc.GetTextExtent(wxStripMenuCodes(label, wxStrip_Mnemonics),
                         &width, &height);

        int x;
        int y = height;

        // first we need to correctly paint the background of the label
        // as Windows ignores the brush offset when doing it
        //
        // FIXME: value of x is hardcoded as this is what it is on my system,
        //        no idea if it's true everywhere
        RECT dimensions = {0, 0, 0, y};
        if ( !rtl )
        {
            x = 9;
            dimensions.left = x;
            dimensions.right = x + width;
        }
        else
        {
            x = rc.right - 7;
            dimensions.left = x - width;
            dimensions.right = x;
        }

        // need to adjust the rectangle to cover all the label background
        dimensions.left -= 2;
        dimensions.right += 2;
        dimensions.bottom += 2;

        if ( UseBgCol() )
        {
            // our own background colour should be used for the background of
            // the label: this is consistent with the behaviour under pre-XP
            // systems (i.e. without visual themes) and generally makes sense
            wxBrush brush = wxBrush(GetBackgroundColour());
            wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
            ::FillRect(GetHdcOf(*impl), &dimensions, GetHbrushOf(brush));
        }
        else // paint parent background
        {
            PaintBackground(dc, dimensions);
        }

        UINT drawTextFlags = DT_SINGLELINE | DT_VCENTER;

        // determine the state of UI queues to draw the text correctly under XP
        // and later systems
        static const bool isXPorLater = wxGetWinVersion() >= wxWinVersion_XP;
        if ( isXPorLater )
        {
            if ( ::SendMessage(GetHwnd(), WM_QUERYUISTATE, 0, 0) &
                    UISF_HIDEACCEL )
            {
                drawTextFlags |= DT_HIDEPREFIX;
            }
        }

        // now draw the text
        if ( !rtl )
        {
            RECT rc2 = { x, 0, x + width, y };
            ::DrawText(hdc, label.t_str(), label.length(), &rc2,
                       drawTextFlags);
        }
        else // RTL
        {
            RECT rc2 = { x, 0, x - width, y };
            ::DrawText(hdc, label.t_str(), label.length(), &rc2,
                       drawTextFlags | DT_RTLREADING);
        }
    }
}
Beispiel #4
0
void wxAuiMSWToolBarArt::DrawButton(
    wxDC& dc,
    wxWindow* wnd,
    const wxAuiToolBarItem& item,
    const wxRect& rect)
{
    if ( m_themed )
    {
        RECT r;
        wxCopyRectToRECT(rect, r);

        wxUxThemeHandle hTheme(wnd, L"Toolbar");

        wxUxThemeEngine* te = wxUxThemeEngine::Get();

        int btnState;
        if ( item.GetState() & wxAUI_BUTTON_STATE_DISABLED )
            btnState = TS_DISABLED;
        else if ( item.GetState() & wxAUI_BUTTON_STATE_PRESSED )
            btnState = TS_PRESSED;
        else if ( item.GetState() & wxAUI_BUTTON_STATE_HOVER &&
            item.GetState() & wxAUI_BUTTON_STATE_CHECKED )
            btnState = TS_HOTCHECKED;
        else if ( item.GetState() & wxAUI_BUTTON_STATE_CHECKED )
            btnState = TS_CHECKED;
        else if ( item.GetState() & wxAUI_BUTTON_STATE_HOVER )
            btnState = TS_HOT;
        else
            btnState = TS_NORMAL;

        te->DrawThemeBackground(
            hTheme,
            GetHdcOf(dc.GetTempHDC()),
            TP_BUTTON,
            btnState,
            &r,
            NULL);

        int textWidth = 0, textHeight = 0;

        if ( m_flags & wxAUI_TB_TEXT )
        {
            dc.SetFont(m_font);

            int tx, ty;

            dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
            textWidth = 0;
            dc.GetTextExtent(item.GetLabel(), &textWidth, &ty);
        }

        int bmpX = 0, bmpY = 0;
        int textX = 0, textY = 0;

        if ( m_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM )
        {
            bmpX = rect.x +
                (rect.width / 2) -
                (item.GetBitmap().GetWidth() / 2);

            bmpY = rect.y +
                ((rect.height - textHeight) / 2) -
                (item.GetBitmap().GetHeight() / 2);

            textX = rect.x + (rect.width / 2) - (textWidth / 2) + 1;
            textY = rect.y + rect.height - textHeight - 1;
        }
        else if ( m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT )
        {
            bmpX = rect.x + 3;

            bmpY = rect.y +
                (rect.height / 2) -
                (item.GetBitmap().GetHeight() / 2);

            textX = bmpX + 3 + item.GetBitmap().GetWidth();
            textY = rect.y +
                (rect.height / 2) -
                (textHeight / 2);
        }

        wxBitmap bmp;
        if ( item.GetState() & wxAUI_BUTTON_STATE_DISABLED )
            bmp = item.GetDisabledBitmap();
        else
            bmp = item.GetBitmap();

        if ( bmp.IsOk() )
            dc.DrawBitmap(bmp, bmpX, bmpY, true);

        // set the item's text color based on if it is disabled
        dc.SetTextForeground(*wxBLACK);
        if ( item.GetState() & wxAUI_BUTTON_STATE_DISABLED )
            dc.SetTextForeground(DISABLED_TEXT_COLOR);

        if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() )
        {
            dc.DrawText(item.GetLabel(), textX, textY);
        }
    }
    else
        wxAuiGenericToolBarArt::DrawButton(dc, wnd, item, rect);
}
Beispiel #5
0
void wxAuiMSWToolBarArt::DrawDropDownButton(
    wxDC& dc,
    wxWindow* wnd,
    const wxAuiToolBarItem& item,
    const wxRect& rect)
{
    if ( m_themed )
    {
        wxUxThemeHandle hTheme(wnd, L"Toolbar");
        wxUxThemeEngine* const te = wxUxThemeEngine::Get();

        int dropDownWidth = 14;

        int textWidth = 0, textHeight = 0, textX = 0, textY = 0;
        int bmpX = 0, bmpY = 0, dropBmpX = 0, dropBmpY = 0;

        wxRect buttonRect = wxRect(rect.x,
            rect.y,
            rect.width - dropDownWidth,
            rect.height);
        wxRect dropDownRect = wxRect(rect.x + rect.width - dropDownWidth - 1,
            rect.y,
            dropDownWidth + 1,
            rect.height);

        if ( m_flags & wxAUI_TB_TEXT )
        {
            dc.SetFont(m_font);

            int tx, ty;
            if ( m_flags & wxAUI_TB_TEXT )
            {
                dc.GetTextExtent(wxT("ABCDHgj"), &tx, &textHeight);
                textWidth = 0;
            }

            dc.GetTextExtent(item.GetLabel(), &textWidth, &ty);
        }

        RECT btnR;
        wxCopyRectToRECT(buttonRect, btnR);
        RECT dropDownR;
        wxCopyRectToRECT(dropDownRect, dropDownR);

        int btnState;
        if ( item.GetState() & wxAUI_BUTTON_STATE_DISABLED )
            btnState = TS_DISABLED;
        else if ( item.GetState() & wxAUI_BUTTON_STATE_PRESSED )
            btnState = TS_PRESSED;
        else if ( item.GetState() & wxAUI_BUTTON_STATE_HOVER )
            btnState = TS_HOT;
        else
            btnState = TS_NORMAL;

        te->DrawThemeBackground(
            hTheme,
            GetHdcOf(dc.GetTempHDC()),
            TP_SPLITBUTTON,
            btnState,
            &btnR,
            NULL);

        te->DrawThemeBackground(
            hTheme,
            GetHdcOf(dc.GetTempHDC()),
            TP_SPLITBUTTONDROPDOWN,
            btnState,
            &dropDownR,
            NULL);

        dropBmpX = dropDownRect.x +
            (dropDownRect.width / 2) -
            (m_buttonDropDownBmp.GetWidth() / 2);
        dropBmpY = dropDownRect.y +
            (dropDownRect.height / 2) -
            (m_buttonDropDownBmp.GetHeight() / 2);


        if ( m_textOrientation == wxAUI_TBTOOL_TEXT_BOTTOM )
        {
            bmpX = buttonRect.x +
                (buttonRect.width / 2) -
                (item.GetBitmap().GetWidth() / 2);
            bmpY = buttonRect.y +
                ((buttonRect.height - textHeight) / 2) -
                (item.GetBitmap().GetHeight() / 2);

            textX = rect.x + (rect.width / 2) - (textWidth / 2) + 1;
            textY = rect.y + rect.height - textHeight - 1;
        }
        else if ( m_textOrientation == wxAUI_TBTOOL_TEXT_RIGHT )
        {
            bmpX = rect.x + 3;

            bmpY = rect.y +
                (rect.height / 2) -
                (item.GetBitmap().GetHeight() / 2);

            textX = bmpX + 3 + item.GetBitmap().GetWidth();
            textY = rect.y +
                (rect.height / 2) -
                (textHeight / 2);
        }

        wxBitmap bmp;
        if ( item.GetState() & wxAUI_BUTTON_STATE_DISABLED )
        {
            bmp = item.GetDisabledBitmap();
        }
        else
        {
            bmp = item.GetBitmap();
        }

        if ( !bmp.IsOk() )
            return;

        dc.DrawBitmap(bmp, bmpX, bmpY, true);

        // set the item's text color based on if it is disabled
        dc.SetTextForeground(*wxBLACK);
        if ( item.GetState() & wxAUI_BUTTON_STATE_DISABLED )
            dc.SetTextForeground(DISABLED_TEXT_COLOR);

        if ( (m_flags & wxAUI_TB_TEXT) && !item.GetLabel().empty() )
        {
            dc.DrawText(item.GetLabel(), textX, textY);
        }

    }
    else
        wxAuiGenericToolBarArt::DrawDropDownButton(dc, wnd, item, rect);
}
Beispiel #6
0
void wxComboCtrl::OnPaintEvent( wxPaintEvent& WXUNUSED(event) )
{
    // TODO: Convert drawing in this function to Windows API Code

    wxSize sz = GetClientSize();
    wxDC* dcPtr = wxAutoBufferedPaintDCFactory(this);
    wxDC& dc = *dcPtr;

    const wxRect& rectButton = m_btnArea;
    wxRect rectTextField = m_tcArea;

    // FIXME: Either SetBackgroundColour or GetBackgroundColour
    //        doesn't work under Vista, so here's a temporary
    //        workaround.
    //        In the theme-less rendering code below, this fixes incorrect
    //        background on read-only comboboxes (they are gray, but should be
    //        white).
    wxColour bgCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);

#if wxUSE_UXTHEME
    const bool isEnabled = IsThisEnabled();

    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
    HDC hDc = GetHdcOf(*impl);
    HWND hWnd = GetHwndOf(this);

    wxUxThemeHandle hTheme(this, L"COMBOBOX");
#endif // wxUSE_UXTHEME

    wxRect borderRect(0,0,sz.x,sz.y);

    if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE )
    {
        borderRect = m_tcArea;
        borderRect.Inflate(1);
    }

    int drawButFlags = 0;

#if wxUSE_UXTHEME
    if ( hTheme )
    {
        const bool useVistaComboBox = ::wxGetWinVersion() >= wxWinVersion_Vista;

        RECT rFull;
        wxCopyRectToRECT(borderRect, rFull);

        RECT rButton;
        wxCopyRectToRECT(rectButton, rButton);

        RECT rBorder;
        wxCopyRectToRECT(borderRect, rBorder);

        bool isNonStdButton = (m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE) ||
                              (m_iFlags & wxCC_IFLAG_HAS_NONSTANDARD_BUTTON);

        //
        // Get some states for themed drawing
        int butState;

        if ( !isEnabled )
        {
            butState = CBXS_DISABLED;
        }
        // Vista will display the drop-button as depressed always
        // when the popup window is visilbe
        else if ( (m_btnState & wxCONTROL_PRESSED) ||
                  (useVistaComboBox && !IsPopupWindowState(Hidden)) )
        {
            butState = CBXS_PRESSED;
        }
        else if ( m_btnState & wxCONTROL_CURRENT )
        {
            butState = CBXS_HOT;
        }
        else
        {
            butState = CBXS_NORMAL;
        }

        int comboBoxPart = 0;  // For XP, use the 'default' part
        RECT* rUseForBg = &rBorder;

        bool drawFullButton = false;
        int bgState = butState;
        const bool isFocused = (FindFocus() == GetMainWindowOfCompositeControl()) ? true : false;

        if ( useVistaComboBox )
        {
            // Draw the entire control as a single button?
            if ( !isNonStdButton )
            {
                if ( HasFlag(wxCB_READONLY) )
                    drawFullButton = true;
            }

            if ( drawFullButton )
            {
                comboBoxPart = CP_READONLY;
                rUseForBg = &rFull;

                // It should be safe enough to update this flag here.
                m_iFlags |= wxCC_FULL_BUTTON;
            }
            else
            {
                comboBoxPart = CP_BORDER;
                m_iFlags &= ~wxCC_FULL_BUTTON;

                if ( isFocused )
                    bgState = CBB_FOCUSED;
                else
                    bgState = CBB_NORMAL;
            }
        }

        //
        // Draw parent's background, if necessary
        RECT* rUseForTb = NULL;

        if ( ::IsThemeBackgroundPartiallyTransparent( hTheme, comboBoxPart, bgState ) )
            rUseForTb = &rFull;
        else if ( m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE )
            rUseForTb = &rButton;

        if ( rUseForTb )
            ::DrawThemeParentBackground( hWnd, hDc, rUseForTb );

        //
        // Draw the control background (including the border)
        if ( m_widthCustomBorder > 0 )
        {
            ::DrawThemeBackground( hTheme, hDc, comboBoxPart, bgState, rUseForBg, NULL );
        }
        else
        {
            // No border. We can't use theme, since it cannot be relied on
            // to deliver borderless drawing, even with DrawThemeBackgroundEx.
            dc.SetBrush(bgCol);
            dc.SetPen(bgCol);
            dc.DrawRectangle(borderRect);
        }

        //
        // Draw the drop-button
        if ( !isNonStdButton )
        {
            drawButFlags = Button_BitmapOnly;

            int butPart = CP_DROPDOWNBUTTON;

            if ( useVistaComboBox )
            {
                if ( drawFullButton )
                {
                    // We need to alter the button style slightly before
                    // drawing the actual button (but it was good above
                    // when background etc was done).
                    if ( butState == CBXS_HOT || butState == CBXS_PRESSED )
                        butState = CBXS_NORMAL;
                }

                if ( m_btnSide == wxRIGHT )
                    butPart = CP_DROPDOWNBUTTONRIGHT;
                else
                    butPart = CP_DROPDOWNBUTTONLEFT;

            }
            ::DrawThemeBackground( hTheme, hDc, butPart, butState, &rButton, NULL );
        }
        else if ( useVistaComboBox &&
                  (m_iFlags & wxCC_IFLAG_BUTTON_OUTSIDE) )
        {
            // We'll do this, because DrawThemeParentBackground
            // doesn't seem to be reliable on Vista.
            drawButFlags |= Button_PaintBackground;
        }
    }
    else
#endif
    {
        // Windows 2000 and earlier
        drawButFlags = Button_PaintBackground;

        dc.SetBrush(bgCol);
        dc.SetPen(bgCol);
        dc.DrawRectangle(borderRect);
    }

    // Button rendering (may only do the bitmap on button, depending on the flags)
    DrawButton( dc, rectButton, drawButFlags );

    // Paint required portion of the custom image on the control
    if ( (!m_text || m_widthCustomPaint) )
    {
        wxASSERT( m_widthCustomPaint >= 0 );

        // this is intentionally here to allow drawed rectangle's
        // right edge to be hidden
        if ( m_text )
            rectTextField.width = m_widthCustomPaint;

        dc.SetFont( GetFont() );

        dc.SetClippingRegion(rectTextField);
        if ( m_popupInterface )
            m_popupInterface->PaintComboControl(dc,rectTextField);
        else
            wxComboPopup::DefaultPaintComboControl(this,dc,rectTextField);
    }

    delete dcPtr;
}
Beispiel #7
0
void wxStaticBox::PaintForeground(wxDC& dc, const RECT& rc)
{
    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
    MSWDefWindowProc(WM_PAINT, (WPARAM)GetHdcOf(*impl), 0);

    // when using XP themes, neither setting the text colour nor transparent
    // background mode doesn't change anything: the static box def window proc
    // still draws the label in its own colours, so we need to redraw the text
    // ourselves if we have a non default fg colour
    if ( m_hasFgCol && wxUxThemeEngine::GetIfActive() )
    {
        // draw over the text in default colour in our colour
        HDC hdc = GetHdcOf(*impl);
        ::SetTextColor(hdc, GetForegroundColour().GetPixel());

        const bool rtl = wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft;
        if ( rtl )
            ::SetTextAlign(hdc, TA_RTLREADING | TA_RIGHT);

        // Get dimensions of the label
        const wxString label = GetLabel();

        // choose the correct font
        AutoHFONT font;
        SelectInHDC selFont;
        if ( m_hasFont )
        {
            selFont.Init(hdc, GetHfontOf(GetFont()));
        }
        else // no font set, use the one set by the theme
        {
            wxUxThemeHandle hTheme(this, L"BUTTON");
            if ( hTheme )
            {
                // GetThemeFont() expects its parameter to be LOGFONTW and not
                // LOGFONTA even in ANSI programs and will happily corrupt
                // memory after the struct end if we pass a LOGFONTA (which is
                // smaller) to it!
                LOGFONTW lfw;
                if ( wxUxThemeEngine::Get()->GetThemeFont
                                             (
                                                hTheme,
                                                hdc,
                                                BP_GROUPBOX,
                                                GBS_NORMAL,
                                                TMT_FONT,
                                                (LOGFONT *)&lfw
                                             ) == S_OK )
                {
#if wxUSE_UNICODE
                    // ok, no conversion necessary
                    const LOGFONT& lf = lfw;
#else // !wxUSE_UNICODE
                    // most of the fields are the same in LOGFONTA and LOGFONTW
                    LOGFONT lf;
                    memcpy(&lf, &lfw, sizeof(lf));

                    // but the face name must be converted
                    WideCharToMultiByte(CP_ACP, 0, lfw.lfFaceName, -1,
                                        lf.lfFaceName, sizeof(lf.lfFaceName),
                                        NULL, NULL);
#endif // wxUSE_UNICODE/!wxUSE_UNICODE

                    font.Init(lf);
                    if ( font )
                        selFont.Init(hdc, font);
                }
            }
        }

        // Get the font extent
        int width, height;
        dc.GetTextExtent(wxStripMenuCodes(label, wxStrip_Mnemonics),
                         &width, &height);

        int x;
        int y = height;

        // first we need to correctly paint the background of the label
        // as Windows ignores the brush offset when doing it
        //
        // FIXME: value of x is hardcoded as this is what it is on my system,
        //        no idea if it's true everywhere
        RECT dimensions = {0, 0, 0, y};
        if ( !rtl )
        {
            x = 9;
            dimensions.left = x;
            dimensions.right = x + width;
        }
        else
        {
            x = rc.right - 7;
            dimensions.left = x - width;
            dimensions.right = x;
        }

        // need to adjust the rectangle to cover all the label background
        dimensions.left -= 2;
        dimensions.right += 2;
        dimensions.bottom += 2;

        if ( UseBgCol() )
        {
            // our own background colour should be used for the background of
            // the label: this is consistent with the behaviour under pre-XP
            // systems (i.e. without visual themes) and generally makes sense
            wxBrush brush = wxBrush(GetBackgroundColour());
            wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
            ::FillRect(GetHdcOf(*impl), &dimensions, GetHbrushOf(brush));
        }
        else // paint parent background
        {
            PaintBackground(dc, dimensions);
        }

        // now draw the text
        if ( !rtl )
        {
            RECT rc2 = { x, 0, x + width, y };
            ::DrawText(hdc, label.wx_str(), label.length(), &rc2,
                       DT_SINGLELINE | DT_VCENTER);
        }
        else // RTL
        {
            RECT rc2 = { x, 0, x - width, y };
            ::DrawText(hdc, label.wx_str(), label.length(), &rc2,
                       DT_SINGLELINE | DT_VCENTER | DT_RTLREADING);
        }
    }
}
Beispiel #8
0
void wxWindowsPrintPreview::DetermineScaling()
{
    ScreenHDC dc;
    int logPPIScreenX = ::GetDeviceCaps(dc, LOGPIXELSX);
    int logPPIScreenY = ::GetDeviceCaps(dc, LOGPIXELSY);
    m_previewPrintout->SetPPIScreen(logPPIScreenX, logPPIScreenY);

    // Get a device context for the currently selected printer
    wxPrinterDC printerDC(m_printDialogData.GetPrintData());

    int printerWidthMM;
    int printerHeightMM;
    int printerXRes;
    int printerYRes;
    int logPPIPrinterX;
    int logPPIPrinterY;

    wxRect paperRect;

    if ( printerDC.IsOk() )
    {
        wxPrinterDCImpl *impl = (wxPrinterDCImpl*) printerDC.GetImpl();
        HDC hdc = GetHdcOf(*impl);
        printerWidthMM = ::GetDeviceCaps(hdc, HORZSIZE);
        printerHeightMM = ::GetDeviceCaps(hdc, VERTSIZE);
        printerXRes = ::GetDeviceCaps(hdc, HORZRES);
        printerYRes = ::GetDeviceCaps(hdc, VERTRES);
        logPPIPrinterX = ::GetDeviceCaps(hdc, LOGPIXELSX);
        logPPIPrinterY = ::GetDeviceCaps(hdc, LOGPIXELSY);

        paperRect = printerDC.GetPaperRect();

        if ( logPPIPrinterX == 0 ||
                logPPIPrinterY == 0 ||
                    printerWidthMM == 0 ||
                        printerHeightMM == 0 )
        {
            m_isOk = false;
        }
    }
    else
    {
        // use some defaults
        printerWidthMM = 150;
        printerHeightMM = 250;
        printerXRes = 1500;
        printerYRes = 2500;
        logPPIPrinterX = 600;
        logPPIPrinterY = 600;

        paperRect = wxRect(0, 0, printerXRes, printerYRes);
        m_isOk = false;
    }
    m_pageWidth = printerXRes;
    m_pageHeight = printerYRes;
    m_previewPrintout->SetPageSizePixels(printerXRes, printerYRes);
    m_previewPrintout->SetPageSizeMM(printerWidthMM, printerHeightMM);
    m_previewPrintout->SetPaperRectPixels(paperRect);
    m_previewPrintout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY);

    // At 100%, the page should look about page-size on the screen.
    m_previewScaleX = float(logPPIScreenX) / logPPIPrinterX;
    m_previewScaleY = float(logPPIScreenY) / logPPIPrinterY;
}
Beispiel #9
0
bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
{
    sm_abortIt = false;
    sm_abortWindow = NULL;

    if (!printout)
    {
        sm_lastError = wxPRINTER_ERROR;
        return false;
    }

    if (m_printDialogData.GetMinPage() < 1)
        m_printDialogData.SetMinPage(1);
    if (m_printDialogData.GetMaxPage() < 1)
        m_printDialogData.SetMaxPage(9999);

    // Create a suitable device context
    wxPrinterDC *dc wxDUMMY_INITIALIZE(NULL);
    if (prompt)
    {
        dc = wxDynamicCast(PrintDialog(parent), wxPrinterDC);
        if (!dc)
            return false;
    }
    else
    {
        dc = new wxPrinterDC(m_printDialogData.GetPrintData());
    }

    // May have pressed cancel.
    if (!dc || !dc->IsOk())
    {
        if (dc) delete dc;
        return false;
    }

    wxPrinterDCImpl *impl = (wxPrinterDCImpl*) dc->GetImpl();

    HDC hdc = ::GetDC(NULL);
    int logPPIScreenX = ::GetDeviceCaps(hdc, LOGPIXELSX);
    int logPPIScreenY = ::GetDeviceCaps(hdc, LOGPIXELSY);
    ::ReleaseDC(NULL, hdc);

    int logPPIPrinterX = ::GetDeviceCaps((HDC) impl->GetHDC(), LOGPIXELSX);
    int logPPIPrinterY = ::GetDeviceCaps((HDC) impl->GetHDC(), LOGPIXELSY);
    if (logPPIPrinterX == 0 || logPPIPrinterY == 0)
    {
        delete dc;
        sm_lastError = wxPRINTER_ERROR;
        return false;
    }

    printout->SetPPIScreen(logPPIScreenX, logPPIScreenY);
    printout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY);

    // Set printout parameters
    printout->SetDC(dc);

    int w, h;
    dc->GetSize(&w, &h);
    printout->SetPageSizePixels((int)w, (int)h);
    printout->SetPaperRectPixels(dc->GetPaperRect());

    dc->GetSizeMM(&w, &h);
    printout->SetPageSizeMM((int)w, (int)h);

    // Create an abort window
    wxBusyCursor busyCursor;

    printout->OnPreparePrinting();

    // Get some parameters from the printout, if defined
    int fromPage, toPage;
    int minPage, maxPage;
    printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);

    if (maxPage == 0)
    {
        sm_lastError = wxPRINTER_ERROR;
        return false;
    }

    // Only set min and max, because from and to have been
    // set by the user
    m_printDialogData.SetMinPage(minPage);
    m_printDialogData.SetMaxPage(maxPage);

    wxPrintAbortDialog *win = CreateAbortWindow(parent, printout);
    wxYield();

    ::SetAbortProc(GetHdcOf(*impl), wxAbortProc);

    if (!win)
    {
        wxLogDebug(wxT("Could not create an abort dialog."));
        sm_lastError = wxPRINTER_ERROR;

        delete dc;
        return false;
    }
    sm_abortWindow = win;
    sm_abortWindow->Show();
    wxSafeYield();

    printout->OnBeginPrinting();

    sm_lastError = wxPRINTER_NO_ERROR;

    int minPageNum = minPage, maxPageNum = maxPage;

    if ( !m_printDialogData.GetAllPages() )
    {
        minPageNum = m_printDialogData.GetFromPage();
        maxPageNum = m_printDialogData.GetToPage();
    }

    // The dc we get from the PrintDialog will do multiple copies without help
    // if the device supports it. Loop only if we have created a dc from our
    // own m_printDialogData or the device does not support multiple copies.
    // m_printDialogData.GetPrintData().GetNoCopies() is set from device
    // devMode in printdlg.cpp/wxWindowsPrintDialog::ConvertFromNative()
    const int maxCopyCount = !prompt ||
                             !m_printDialogData.GetPrintData().GetNoCopies()
                             ? m_printDialogData.GetNoCopies() : 1;
    for ( int copyCount = 1; copyCount <= maxCopyCount; copyCount++ )
    {
        if ( !printout->OnBeginDocument(minPageNum, maxPageNum) )
        {
            wxLogError(_("Could not start printing."));
            sm_lastError = wxPRINTER_ERROR;
            break;
        }
        if (sm_abortIt)
        {
            sm_lastError = wxPRINTER_CANCELLED;
            break;
        }

        int pn;

        for ( pn = minPageNum;
              pn <= maxPageNum && printout->HasPage(pn);
              pn++ )
        {
            win->SetProgress(pn - minPageNum + 1,
                             maxPageNum - minPageNum + 1,
                             copyCount, maxCopyCount);

            if ( sm_abortIt )
            {
                sm_lastError = wxPRINTER_CANCELLED;
                break;
            }

            dc->StartPage();
            bool cont = printout->OnPrintPage(pn);
            dc->EndPage();

            if ( !cont )
            {
                sm_lastError = wxPRINTER_CANCELLED;
                break;
            }
        }

        printout->OnEndDocument();
    }

    printout->OnEndPrinting();

    if (sm_abortWindow)
    {
        sm_abortWindow->Show(false);
        wxDELETE(sm_abortWindow);
    }

    delete dc;

    return sm_lastError == wxPRINTER_NO_ERROR;
}
Beispiel #10
0
// draw the item
bool wxOwnerDrawn::OnDrawItem(wxDC& dc, const wxRect& rc,
                              wxODAction, wxODStatus stat)
{
    // we do nothing if item isn't ownerdrawn
    if ( !IsOwnerDrawn() )
        return true;

    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
    HDC hdc = GetHdcOf(*impl);

    RECT rect;
    wxCopyRectToRECT(rc, rect);

    {
        // set the font and colors
        wxFont font;
        GetFontToUse(font);

        wxColour colText, colBack;
        GetColourToUse(stat, colText, colBack);

        SelectInHDC selFont(hdc, GetHfontOf(font));

        wxMSWImpl::wxTextColoursChanger textCol(hdc, colText, colBack);
        wxMSWImpl::wxBkModeChanger bkMode(hdc, wxBRUSHSTYLE_TRANSPARENT);


        AutoHBRUSH hbr(wxColourToPalRGB(colBack));
        SelectInHDC selBrush(hdc, hbr);

        ::FillRect(hdc, &rect, hbr);

        // using native API because it recognizes '&'

        wxString text = GetName();

        SIZE sizeRect;
        ::GetTextExtentPoint32(hdc, text.c_str(), text.length(), &sizeRect);

        int flags = DST_PREFIXTEXT;
        if ( (stat & wxODDisabled) && !(stat & wxODSelected) )
            flags |= DSS_DISABLED;

        if ( (stat & wxODHidePrefix) )
            flags |= DSS_HIDEPREFIX;

        int x = rc.x + GetMarginWidth();
        int y = rc.y + (rc.GetHeight() - sizeRect.cy) / 2;
        int cx = rc.GetWidth() - GetMarginWidth();
        int cy = sizeRect.cy;

        ::DrawState(hdc, NULL, NULL, wxMSW_CONV_LPARAM(text),
                    text.length(), x, y, cx, cy, flags);

    } // reset to default the font, colors and brush

    if (stat & wxODHasFocus)
        ::DrawFocusRect(hdc, &rect);

    return true;
}
Beispiel #11
0
bool wxPrinterDCImpl::DoBlit(wxCoord xdest, wxCoord ydest,
                         wxCoord width, wxCoord height,
                         wxDC *source,
                         wxCoord WXUNUSED(xsrc), wxCoord WXUNUSED(ysrc),
                         wxRasterOperationMode WXUNUSED(rop), bool useMask,
                         wxCoord WXUNUSED(xsrcMask), wxCoord WXUNUSED(ysrcMask))
{
    wxDCImpl *impl = source->GetImpl();
    wxMSWDCImpl *msw_impl = wxDynamicCast(impl, wxMSWDCImpl);
    if (!msw_impl)
        return false;

    wxBitmap& bmp = msw_impl->GetSelectedBitmap();
    wxMask *mask = useMask ? bmp.GetMask() : NULL;
    if ( mask )
    {
        // If we are printing source colours are screen colours not printer
        // colours and so we need copy the bitmap pixel by pixel.
        RECT rect;
        HDC dcSrc = GetHdcOf(*msw_impl);
        MemoryHDC dcMask(dcSrc);
        SelectInHDC selectMask(dcMask, (HBITMAP)mask->GetMaskBitmap());

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                COLORREF cref = ::GetPixel(dcMask, x, y);
                if (cref)
                {
                    HBRUSH brush = ::CreateSolidBrush(::GetPixel(dcSrc, x, y));
                    rect.left = xdest + x;
                    rect.right = rect.left + 1;
                    rect.top = ydest + y;
                    rect.bottom = rect.top + 1;
                    ::FillRect(GetHdc(), &rect, brush);
                    ::DeleteObject(brush);
                }
            }
        }
    }
    else // no mask
    {
        if ( !(::GetDeviceCaps(GetHdc(), RASTERCAPS) & RC_STRETCHDIB) ||
                !DrawBitmapUsingStretchDIBits(GetHdc(), bmp, xdest, ydest) )
        {
            // no support for StretchDIBits

            // as we are printing, source colours are screen colours not
            // printer colours and so we need copy the bitmap pixel by pixel.
            HDC dcSrc = GetHdcOf(*msw_impl);
            RECT rect;
            for (int y = 0; y < height; y++)
            {
                // optimization: draw identical adjacent pixels together.
                for (int x = 0; x < width; x++)
                {
                    COLORREF col = ::GetPixel(dcSrc, x, y);
                    HBRUSH brush = ::CreateSolidBrush( col );

                    rect.left = xdest + x;
                    rect.top = ydest + y;
                    while( (x + 1 < width) &&
                                (::GetPixel(dcSrc, x + 1, y) == col ) )
                    {
                        ++x;
                    }
                    rect.right = xdest + x + 1;
                    rect.bottom = rect.top + 1;
                    ::FillRect((HDC) m_hDC, &rect, brush);
                    ::DeleteObject(brush);
                }
            }
        }
    }

    return true;
}
Beispiel #12
0
void wxAuiMSWTabArt::DrawButton(wxDC& dc,
    wxWindow* wnd,
    const wxRect& in_rect,
    int bitmap_id,
    int button_state,
    int orientation,
    wxRect* out_rect)
{
    if ( !IsThemed() )
    {
        wxAuiGenericTabArt::DrawButton(dc, wnd, in_rect, bitmap_id, button_state, orientation, out_rect);
        return;
    }

    const wchar_t* themeId = NULL;
    int part = 0;

    switch (bitmap_id)
    {
    case wxAUI_BUTTON_CLOSE:
        themeId = L"Window";
        part = WP_CLOSEBUTTON;
        break;
    case wxAUI_BUTTON_LEFT:
        themeId = L"Spin";
        part = SPNP_DOWNHORZ;
        break;
    case wxAUI_BUTTON_RIGHT:
        themeId = L"Spin";
        part = SPNP_UPHORZ;
        break;
    case wxAUI_BUTTON_WINDOWLIST:
        themeId = L"Combobox";
        part = CP_DROPDOWNBUTTON;
        break;
    }

    wxRect rect = in_rect;

    if ( orientation == wxLEFT )
    {
        rect.SetX(in_rect.x);
        rect.SetY(((in_rect.y + in_rect.height) / 2) - (m_closeBtnSize.GetHeight() / 2));
        rect.SetWidth(m_closeBtnSize.GetWidth());
        rect.SetHeight(m_closeBtnSize.GetHeight());
    }
    else
    {
        rect = wxRect(in_rect.x + in_rect.width - m_closeBtnSize.GetWidth(),
            ((in_rect.y + in_rect.height) / 2) - (m_closeBtnSize.GetHeight() / 2),
            m_closeBtnSize.GetWidth(), m_closeBtnSize.GetHeight());
    }

    if ( bitmap_id == wxAUI_BUTTON_LEFT ||
        bitmap_id == wxAUI_BUTTON_RIGHT )
    {
        rect.y = in_rect.y;
        rect.height = in_rect.height - wnd->FromDIP(7);
    }

    dc.SetPen(*wxTRANSPARENT_PEN);
    dc.SetBrush(wxBrush(m_baseColour));
    dc.DrawRectangle(rect);

    int btnState;
    if ( button_state == wxAUI_BUTTON_STATE_DISABLED )
        btnState = TTCS_PRESSED + 1;
    else if ( button_state == wxAUI_BUTTON_STATE_HOVER )
        btnState = TTCS_HOT;
    else if ( button_state == wxAUI_BUTTON_STATE_PRESSED )
        btnState = TTCS_PRESSED;
    else
        btnState = TTCS_NORMAL;

    wxUxThemeHandle hTheme(wnd, themeId);

    wxRect btnRect(rect);
    btnRect.width -= wnd->FromDIP(1);

    RECT btnR;
    wxCopyRectToRECT(btnRect, btnR);
    ::DrawThemeBackground(hTheme, GetHdcOf(dc.GetTempHDC()), part, btnState, &btnR, NULL);

    if ( out_rect )
        *out_rect = rect;
}
Beispiel #13
0
void wxAuiMSWTabArt::DrawTab(wxDC& dc,
    wxWindow* wnd,
    const wxAuiNotebookPage& page,
    const wxRect& in_rect,
    int close_button_state,
    wxRect* out_tab_rect,
    wxRect* out_button_rect,
    int* x_extent)
{
    if ( !IsThemed() )
    {
        wxAuiGenericTabArt::DrawTab(dc, wnd, page, in_rect, close_button_state, out_tab_rect, out_button_rect, x_extent);
        return;
    }

    if ( !m_closeBtnSize.IsFullySpecified() )
        InitSizes(wnd, dc);

    // figure out the size of the tab
    wxSize tabSize = GetTabSize(dc,
        wnd,
        page.caption,
        page.bitmap,
        page.active,
        close_button_state,
        x_extent);

    wxCoord tabHeight = tabSize.y;
    wxCoord tabWidth = tabSize.x;
    wxCoord tabX = in_rect.x;
    wxCoord tabY = 0;

    if (!page.active)
    {
        tabY += wnd->FromDIP(2);
        tabHeight -= wnd->FromDIP(2);
    }
    else
    {
        tabX -= wnd->FromDIP(2);
        tabWidth += wnd->FromDIP(4);
        tabHeight += 2;
    }

    int clipWidth = tabWidth;
    if ( tabX + clipWidth > in_rect.x + in_rect.width )
        clipWidth = (in_rect.x + in_rect.width) - tabX;
    dc.SetClippingRegion(tabX - wnd->FromDIP(2), tabY, clipWidth + wnd->FromDIP(4), tabHeight);


    // draw tab
    wxRect tabRect(tabX, tabY, tabWidth, tabHeight);

    int tabState;
    if ( page.active )
        tabState = TIS_SELECTED;
    else if ( page.hover )
        tabState = TIS_HOT;
    else
        tabState = TIS_NORMAL;

    wxUxThemeHandle hTabTheme(wnd, L"Tab");
    RECT tabR;
    wxCopyRectToRECT(tabRect, tabR);
    ::DrawThemeBackground(hTabTheme, GetHdcOf(dc.GetTempHDC()), TABP_TABITEM,
        tabState,
        &tabR, NULL);

    // Apparently, in at least some Windows 10 installations the call above
    // does not draw the left edge of the first tab and it needs to be drawn
    // separately, or it wouldn't be drawn at all.
    if ( tabX == GetIndentSize() )
    {
        ::DrawThemeBackground
            (
                hTabTheme,
                GetHdcOf(dc.GetTempHDC()),
                TABP_TABITEMLEFTEDGE,
                tabState,
                &tabR,
                NULL
            );
    }

    wxRect textRect = tabRect;
    if ( !page.active )
        textRect.Offset(0, wnd->FromDIP(1));
    if ( close_button_state != wxAUI_BUTTON_STATE_HIDDEN )
        textRect.width -= m_closeBtnSize.x + wnd->FromDIP(3);

    dc.SetFont(wnd->GetFont());
    dc.DrawLabel(page.caption, page.bitmap, textRect, wxALIGN_CENTRE);

    // draw focus rectangle
    if ( page.active && (wnd->FindFocus() == wnd) )
    {
        wxRect focusRect = tabRect;
        focusRect.Deflate(wnd->FromDIP(2));

        wxRendererNative::Get().DrawFocusRect(wnd, dc, focusRect, 0);
    }

    // draw close button
    if ( close_button_state != wxAUI_BUTTON_STATE_HIDDEN )
    {
        wxUxThemeHandle hToolTipTheme(wnd, L"TOOLTIP");

        int btnState;
        if ( close_button_state == wxAUI_BUTTON_STATE_HOVER )
            btnState = TTCS_HOT;
        else if ( close_button_state == wxAUI_BUTTON_STATE_PRESSED )
            btnState = TTCS_PRESSED;
        else
            btnState = TTCS_NORMAL;

        int offsetY = tabY;
        if ( wxGetWinVersion() < wxWinVersion_Vista )
            offsetY++; // WinXP theme needs a little more padding

        wxRect rect(tabX + tabWidth - m_closeBtnSize.x - wnd->FromDIP(4),
            offsetY + (tabHeight / 2) - (m_closeBtnSize.y / 2),
            m_closeBtnSize.x,
            m_closeBtnSize.y);

        RECT btnR;
        wxCopyRectToRECT(rect, btnR);
        ::DrawThemeBackground(hToolTipTheme, GetHdcOf(dc.GetTempHDC()), TTP_CLOSE, btnState, &btnR, NULL);

        if ( out_button_rect )
            *out_button_rect = rect;
    }

    *out_tab_rect = wxRect(tabX, tabY, tabWidth, tabHeight);

    dc.DestroyClippingRegion();
}
Beispiel #14
0
void GutterCtrl::DrawGutter(wxDC& dc) {
	Lines& lines = m_editorCtrl.m_lines;

	const wxSize size = GetClientSize();
	m_mdc.Clear();

	const unsigned int bg_xpos = m_gutterLeft ? size.x-1 : 0;
	const unsigned int edge_xpos = m_gutterLeft ? size.x-2 : 1;

	// Draw the edge
	m_mdc.SetPen(m_theme.backgroundColor);
	m_mdc.DrawLine(bg_xpos, 0, bg_xpos, size.y);
	m_mdc.SetPen(m_edgecolor);
	m_mdc.DrawLine(edge_xpos, 0, edge_xpos, size.y);

	// Draw the line numbers
	m_mdc.SetTextForeground(m_numbercolor);
	wxString number;
	const int scrollPos = m_editorCtrl.scrollPos;

	const unsigned int firstline = lines.GetLineFromYPos(scrollPos);
	const unsigned int linecount = lines.GetLineCount();

	// Prepare for foldings
	const vector<cxFold>& folds = m_editorCtrl.GetFolds();
	vector<cxFold>::const_iterator nextFold = folds.begin();
	const unsigned int line_middle = lines.GetLineHeight() / 2;
	vector<const cxFold*> foldStack;
	if (m_showFolds) {
		m_editorCtrl.UpdateFolds();

#ifdef __WXDEBUG__
		bool debug = false;
		if (debug) {
			for (vector<cxFold>::const_iterator f = folds.begin(); f != folds.end(); ++f) {
				const wxString indent(wxT('.'), f->indent);
				wxLogDebug(wxT("%d: %s%d"), f->line_id, indent.c_str(), f->type);
			}
		}
#endif

		for (nextFold = folds.begin(); nextFold != folds.end() && nextFold->line_id < firstline; ++nextFold) {
			if (nextFold->type != cxFOLD_END) {
				foldStack.push_back(&*nextFold);
				continue;
			}

			// check if end marker matches any starter on the stack
			for (vector<const cxFold*>::reverse_iterator p = foldStack.rbegin(); p != foldStack.rend(); ++p) {
				if ((*p)->indent != nextFold->indent) continue;

				foldStack.erase(p.base()-1, foldStack.end()); // pop
				break;
			}
		}
	}

	// Prepare for bookmarks
	const vector<cxBookmark>& bookmarks = m_editorCtrl.GetBookmarks();
	vector<cxBookmark>::const_iterator nextBookmark = bookmarks.begin();
	while(nextBookmark != bookmarks.end() && nextBookmark->line_id < firstline) ++nextBookmark;

	// Draw each line
	for (unsigned int i = firstline; i < linecount; ++i) {
		number.Printf(wxT("%*u"), m_max_digits, i+1);
		const int ypos = lines.GetYPosFromLine(i) - scrollPos;
		if (ypos > size.y) break;

		// Highlight selections
		if (m_currentSel != -1 &&
			((i >= m_sel_startline && i <= m_sel_endline) ||
			 (i >= m_sel_endline && i <= m_sel_startline))) {

			const int ypos2 = lines.GetBottomYPosFromLine(i) - scrollPos;
			m_mdc.SetPen(m_hlightcolor);
			m_mdc.SetBrush(wxBrush(m_hlightcolor, wxSOLID));
			m_mdc.DrawRectangle(0, ypos, size.x-2, ypos2-ypos);
		}

		// Draw bookmark
		if (m_showBookmarks && nextBookmark != bookmarks.end() && nextBookmark->line_id == i) {
			//m_mdc.DrawText(wxT("\u066D"), 3, ypos);
			m_mdc.DrawBitmap(m_bmBookmark, 2, ypos + line_middle - 5);
			++nextBookmark;
		}

		// Draw the line number
		m_mdc.DrawText(number, m_numberX, ypos);

		// Draw fold markers
		if (m_showFolds) {
			bool drawFoldLine = (!foldStack.empty());

			if (nextFold != folds.end() && nextFold->line_id == i) {
				if (nextFold->type == cxFOLD_START) {
					const int ypos2 = lines.GetBottomYPosFromLine(i) - scrollPos;
					const unsigned int box_y = ypos + line_middle - 5;
					m_mdc.DrawBitmap(m_bmFoldOpen, m_foldStartX, box_y);

					if (&*nextFold == m_currentFold) m_mdc.SetPen(wxPen(m_edgecolor, 2));
					else m_mdc.SetPen(m_edgecolor);
					m_mdc.DrawLine(m_foldStartX+4, box_y+9, m_foldStartX+4, ypos2);

					foldStack.push_back(&*nextFold);
					drawFoldLine = false;
					++nextFold;
				}
				else if (nextFold->type == cxFOLD_START_FOLDED) {
					const unsigned int box_y = ypos + line_middle - 5;
					m_mdc.DrawBitmap(m_bmFoldClosed, m_foldStartX, box_y);
					drawFoldLine = false;

					// Advance to end of fold
					i += nextFold->count;
					while (nextFold != folds.end() && nextFold->line_id <= i) ++nextFold;
				}
				else if (nextFold->type == cxFOLD_END) {
					if (!foldStack.empty()) {
						// check if end marker matches any starter on the stack (ignore unmatched)
						for (vector<const cxFold*>::reverse_iterator f = foldStack.rbegin(); f != foldStack.rend(); ++f) {
							if (nextFold->indent == (*f)->indent) {
								vector<const cxFold*>::iterator fb = (++f).base();

								// Check if we should highlight fold line
								if (*fb == m_currentFold) m_mdc.SetPen(wxPen(m_edgecolor, 2));
								else m_mdc.SetPen(m_edgecolor);

								// If we are closing other folds, we want to leave a gap
								const unsigned int ytop = (fb < foldStack.end()-1) ? ypos + 2 : ypos;

								// Draw end marker
								const unsigned int middle_y = ypos + line_middle+1;
								m_mdc.DrawLine(m_foldStartX+4, ytop, m_foldStartX+4, middle_y);
								m_mdc.DrawLine(m_foldStartX+4, middle_y, m_foldStartX+9, middle_y);

								foldStack.erase(fb, foldStack.end()); // pop
								drawFoldLine = false;
								break;
							}
						}
					}
					++nextFold;
				}
			}

			if (drawFoldLine) {
				const int ypos2 = lines.GetBottomYPosFromLine(i) - scrollPos;

				// Check if we should highlight fold line
				if (!foldStack.empty() && foldStack.back() == m_currentFold) {
					m_mdc.SetPen(wxPen(m_edgecolor, 2));
				}
				else m_mdc.SetPen(m_edgecolor);

				m_mdc.DrawLine(m_foldStartX+4, ypos, m_foldStartX+4, ypos2);
			}
		}
	}

	// Copy MemoryDC to Display
#ifdef __WXMSW__
	::BitBlt(GetHdcOf(dc), 0, 0,(int)size.x, (int)size.y, GetHdcOf(m_mdc), 0, 0, SRCCOPY);
#else
	dc.Blit(0, 0, size.x, size.y, &m_mdc, 0, 0);
#endif
}