Beispiel #1
0
bool wxMenuItem::IsChecked() const
{
    wxCHECK_MSG( m_menuItem, false, wxT("invalid menu item") );

    wxCHECK_MSG( IsCheckable(), false,
                 wxT("can't get state of uncheckable item!") );

    return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(m_menuItem)) != 0;
}
Beispiel #2
0
bool wxMenuItem::IsChecked() const
{
    wxCHECK_MSG( m_menuItem, false, wxT("invalid menu item") );

    wxCHECK_MSG( IsCheckable(), false,
                 wxT("can't get state of uncheckable item!") );

    return ((GtkCheckMenuItem*)m_menuItem)->active != 0;
}
void wxMenuItem::Check(bool bDoCheck)
{
    wxCHECK_RET( IsCheckable() && !IsSeparator(), wxT("only checkable items may be checked") );

    if ( m_isChecked != bDoCheck )
    {
        if ( GetKind() == wxITEM_RADIO )
        {
            if ( bDoCheck )
            {
                wxMenuItemBase::Check( bDoCheck ) ;
                UpdateItemStatus() ;

                // get the index of this item in the menu
                const wxMenuItemList& items = m_parentMenu->GetMenuItems();
                int pos = items.IndexOf(this);
                wxCHECK_RET( pos != wxNOT_FOUND,
                             wxT("menuitem not found in the menu items list?") );

                // get the radio group range
                int start, end;

                if ( m_isRadioGroupStart )
                {
                    // we already have all information we need
                    start = pos;
                    end = m_radioGroup.end;
                }
                else // next radio group item
                {
                    // get the radio group end from the start item
                    start = m_radioGroup.start;
                    end = items.Item(start)->GetData()->m_radioGroup.end;
                }

                // also uncheck all the other items in this radio group
                wxMenuItemList::compatibility_iterator node = items.Item(start);
                for ( int n = start; n <= end && node; n++ )
                {
                    if ( n != pos )
                        ((wxMenuItem*)node->GetData())->UncheckRadio();

                    node = node->GetNext();
                }
            }
        }
        else
        {
            wxMenuItemBase::Check( bDoCheck ) ;
            UpdateItemStatus() ;
        }
    }
}
void wxMenuItem::UpdateItemStatus()
{
    if ( !m_parentMenu )
        return ;

    if ( IsSeparator() )
        return ;

    if ( IsCheckable() && IsChecked() )
        GetPeer()->Check( true );
    else
        GetPeer()->Check( false );

    GetPeer()->Enable( IsEnabled() );
}
Beispiel #5
0
void wxMenuItem::DestroyItem(bool full)
{
    if (GetId() == -3)
    {
        ;      // Nothing

    }
    else if (!m_text.empty() && !m_subMenu)
    {
        if (m_buttonWidget)
        {
            if (IsCheckable())
                XtRemoveCallback ((Widget) m_buttonWidget, XmNvalueChangedCallback,
                wxMenuItemCallback, (XtPointer) this);
            else
                XtRemoveCallback ((Widget) m_buttonWidget, XmNactivateCallback,
                wxMenuItemCallback, (XtPointer) this);
            XtRemoveCallback ((Widget) m_buttonWidget, XmNarmCallback,
                wxMenuItemArmCallback, (XtPointer) this);
            XtRemoveCallback ((Widget) m_buttonWidget, XmNdisarmCallback,
                wxMenuItemDisarmCallback, (XtPointer) this);
        }
    }
    else if (IsSeparator())
    {
        ;      // Nothing

    }
    else if (GetSubMenu())
    {
        if (m_buttonWidget)
        {
            XtRemoveCallback ((Widget) m_buttonWidget, XmNcascadingCallback,
                wxMenuItemArmCallback, (XtPointer) this);
        }
        m_subMenu->DestroyMenu(full);
        if (full)
            m_buttonWidget = NULL;
    }

    if (m_buttonWidget && full)
    {
        XtDestroyWidget ((Widget) m_buttonWidget);
        m_buttonWidget = (WXWidget) 0;
    }
}
Beispiel #6
0
void wxMenuItem::UpdateItemStatus()
{
    if ( !m_parentMenu )
        return ;

    if ( IsSeparator() )
        return ;

#if TARGET_CARBON
    if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macPreferencesMenuItemId)
    {
        if ( !IsEnabled() )
            DisableMenuCommand( NULL , kHICommandPreferences ) ;
        else
            EnableMenuCommand( NULL , kHICommandPreferences ) ;
    }

    if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macExitMenuItemId)
    {
        if ( !IsEnabled() )
            DisableMenuCommand( NULL , kHICommandQuit ) ;
        else
            EnableMenuCommand( NULL , kHICommandQuit ) ;
    }
#endif

    {
        MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
        MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
        if ( mhandle == NULL || index == 0)
            return ;

        UMAEnableMenuItem( mhandle , index , m_isEnabled ) ;
        if ( IsCheckable() && IsChecked() )
            ::SetItemMark( mhandle , index , 0x12 ) ; // checkmark
        else
            ::SetItemMark( mhandle , index , 0 ) ; // no mark

        UMASetMenuItemText( mhandle , index , wxStripMenuCodes(m_text) , wxFont::GetDefaultEncoding() ) ;
        wxAcceleratorEntry *entry = wxAcceleratorEntry::Create( m_text ) ;
        UMASetMenuItemShortcut( mhandle , index , entry ) ;
        delete entry ;
    }
}
Beispiel #7
0
void wxMenuItem::Check(bool bDoCheck)
{
    wxCHECK_RET( IsCheckable(), "only checkable items may be checked" );

    if ( m_isChecked != bDoCheck )
    {
        if ( m_buttonWidget )
        {
            wxASSERT_MSG( XtIsSubclass((Widget)m_buttonWidget,
                                       xmToggleButtonGadgetClass),
                          wxT("checkable menu item must be a toggle button") );

            XtVaSetValues((Widget)m_buttonWidget,
                          XmNset, (Boolean)bDoCheck,
                          NULL);
        }

        wxMenuItemBase::Check(bDoCheck);
    }
}
bool wxMenuItem::OnDrawItem( wxDC& rDC,
                               const wxRect& rRect,
                               wxODAction eAction,
                               wxODStatus eStatus )
{

    //
    // Select the font and draw the text
    // ---------------------------------
    //

    CHARBUNDLE                      vCbnd;
    wxPMDCImpl                      *impl = (wxPMDCImpl*) rDC.GetImpl();
    HPS                             hPS= impl->GetHPS();
    wxFont                          vFont;
    wxColour                        vColBack;
    wxColour                        vColText;
    COLORREF                        vRef;
    RECTL                           vRect = {rRect.x + 4, rRect.y + 1, rRect.x + (rRect.width - 2), rRect.y + rRect.height};

    memset(&vCbnd, 0, sizeof(CHARBUNDLE));

    GetFontToUse(vFont);
    GetColourToUse(eStatus, vColText, vColBack);

    rDC.SetFont(vFont);
    rDC.SetTextBackground(vColBack);
    rDC.SetTextForeground(vColText);
    rDC.SetBackgroundMode(wxTRANSPARENT);

    vCbnd.lColor     = vColText.GetPixel();
    vCbnd.lBackColor = vColBack.GetPixel();
    ::GpiSetAttrs( hPS
                  ,PRIM_CHAR
                  ,CBB_BACK_COLOR | CBB_COLOR
                  ,0
                  ,&vCbnd
                 );
    ::GpiSetBackMix( hPS
                    ,BM_LEAVEALONE
                   );

    //
    // Paint the background
    //
    ::WinFillRect(hPS, &vRect, vColBack.GetPixel());

    //
    // Determine where to draw and leave space for a check-mark.
    //
    int nX = rRect.x + GetMarginWidth();

    //
    // Unfortunately, unlike Win32, PM has no owner drawn specific text
    // drawing methods like ::DrawState that can cleanly handle accel
    // mnemonics and deal, automatically, with various states, so we have
    // to handle them ourselves. Notice Win32 can't handle \t in ownerdrawn
    // strings either.  We cannot handle mnemonics either.  We display
    // them, though, in the hope we can figure them out some day.
    //

    //
    // Display main text and accel text separately to align better
    //
    wxString sTgt = wxT("\t");
    wxString sFullString = GetItemLabel(); // need to save the original text
    wxString sAccel;
    int      nIndex;
    size_t   nWidth;
    size_t   nCharWidth;
    size_t   nHeight;
    bool     bFoundMnemonic = false;
    bool     bFoundAccel = false;

    //
    // Deal with the tab, extracting the Accel text
    //
    nIndex = sFullString.Find(sTgt);
    if (nIndex != -1)
    {
        bFoundAccel = true;
        sAccel = sFullString.Mid(nIndex + 1);
        sFullString.Remove(nIndex);
    }

    //
    // Deal with the mnemonic character
    //
    sTgt = wxT("~");
    nIndex = sFullString.Find(sTgt);
    if (nIndex != -1)
    {
        wxString sTmp = sFullString;

        bFoundMnemonic = true;
        sTmp.Remove(nIndex);
        rDC.GetTextExtent( sTmp
                          ,(wxCoord *)&nWidth
                          ,(wxCoord *)&nHeight
                         );
        sTmp = sFullString[(size_t)(nIndex + 1)];
        rDC.GetTextExtent( sTmp
                          ,(wxCoord *)&nCharWidth
                          ,(wxCoord *)&nHeight
                         );
        sFullString.Replace(sTgt.c_str(), wxEmptyString, true);
    }

    //
    // Draw the main item text sans the accel text
    //
    POINTL                      vPntStart = {nX, rRect.y + 4};
    ::GpiCharStringAt( impl->GetHPS()
                      ,&vPntStart
                      ,sFullString.length()
                      ,sFullString.char_str()
                     );
    if (bFoundMnemonic)
    {
        //
        // Underline the mnemonic -- still won't work, but at least it "looks" right
        //
        wxPen                       vPen;
        POINTL                      vPntEnd = {nX + nWidth + nCharWidth - 3, rRect.y + 2}; //CharWidth is bit wide

        vPntStart.x = nX + nWidth - 1;
        vPntStart.y = rRect.y + 2; // Make it look pretty!
        vPen = wxPen(vColText, 1, wxSOLID); // Assuming we are always black
        rDC.SetPen(vPen);
        ::GpiMove(hPS, &vPntStart);
        ::GpiLine(hPS, &vPntEnd);
    }

    //
    // Now draw the accel text
    //
    if (bFoundAccel)
    {
        size_t                      nWidth;
        size_t                      nHeight;

        rDC.GetTextExtent( sAccel
                          ,(wxCoord *)&nWidth
                          ,(wxCoord *)&nHeight
                         );
        //
        // Back off the starting position from the right edge
        //
        vPntStart.x = rRect.width - (nWidth + 7);
        vPntStart.y = rRect.y + 4;
        ::GpiCharStringAt( impl->GetHPS()
                          ,&vPntStart
                          ,sAccel.length()
                          ,sAccel.char_str()
                         );
    }

    //
    // Draw the bitmap
    // ---------------
    //
    if (IsCheckable() && !m_bmpChecked.IsOk())
    {
        if (eStatus & wxODChecked)
        {
            RECTL                   vRect;
            HBITMAP                 hBmpCheck = ::WinGetSysBitmap(HWND_DESKTOP, SBMP_MENUCHECK);

            vRect.xLeft   = rRect.x;
            vRect.xRight  = rRect.x + GetMarginWidth();
            vRect.yBottom = rRect.y;
            vRect.yTop    = rRect.y + m_nHeight - 3;

            ::WinDrawBitmap( hPS             // PS for this menuitem
                            ,hBmpCheck       // system checkmark
                            ,NULL            // draw the whole bitmap
                            ,(PPOINTL)&vRect // destination -- bottom left corner of the menuitem area
                            ,0L              // ignored
                            ,0L              // draw a bitmap
                            ,DBM_NORMAL      // draw normal size
                           );
        }
    }
    else
    {
        //
        // For uncheckable item we use only the 'checked' bitmap
        //
        wxBitmap vBmp(GetBitmap(IsCheckable() ? ((eStatus & wxODChecked) != 0) : TRUE));

        if (vBmp.IsOk())
        {

            wxMemoryDC              vDCMem(&rDC);
            wxMemoryDC*             pOldDC = (wxMemoryDC*)vBmp.GetSelectedInto();

            if(pOldDC != NULL)
            {
                vBmp.SetSelectedInto(NULL);
            }
            vDCMem.SelectObject(vBmp);

            //
            // Center bitmap
            //
            int                     nBmpWidth = vBmp.GetWidth();
            int                     nBmpHeight = vBmp.GetHeight();

            //
            // There should be enough space!
            //
            wxASSERT((nBmpWidth <= rRect.width) && (nBmpHeight <= rRect.height));

            int                     nHeightDiff = m_nHeight - nBmpHeight;

            rDC.Blit( rRect.x + (GetMarginWidth() - nBmpWidth) / 2
                     ,rRect.y + nHeightDiff / 2
                     ,nBmpWidth
                     ,nBmpHeight
                     ,&vDCMem
                     ,0
                     ,0
                     ,wxCOPY
                     ,true
                    );

            if (eStatus & wxODSelected)
            {
                POINTL              vPnt1 = {rRect.x + 1, rRect.y + 3}; // Leave a little background border
                POINTL              vPnt2 = {rRect.x + GetMarginWidth(), rRect.y + m_nHeight - 3};

                LINEBUNDLE          vLine;

                vLine.lColor = vColBack.GetPixel();
                ::GpiSetAttrs( hPS
                              ,PRIM_LINE
                              ,LBB_COLOR
                              ,0
                              ,&vLine
                             );
                ::GpiMove(hPS, &vPnt1);
                ::GpiBox( hPS
                         ,DRO_OUTLINE
                         ,&vPnt2
                         ,0L
                         ,0L
                        );
            }
            vBmp.SetSelectedInto(NULL);
        }
    }
    return true;
} // end of wxOwnerDrawn::OnDrawItem
void wxMenuItem::Check(
  bool                              bCheck
)
{
    bool                            bOk;

    wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );
    if (m_isChecked == bCheck)
        return;

    HMENU                           hMenu = GetHmenuOf(m_parentMenu);

    if (GetKind() == wxITEM_RADIO)
    {
        //
        // It doesn't make sense to uncheck a radio item - what would this do?
        //
        if (!bCheck)
            return;

        //
        // Get the index of this item in the menu
        //
        const wxMenuItemList&       rItems = m_parentMenu->GetMenuItems();
        int                         nPos = rItems.IndexOf(this);

        wxCHECK_RET( nPos != wxNOT_FOUND
                    ,wxT("menuitem not found in the menu items list?")
                   );

        //
        // Get the radio group range
        //
        int                         nStart;
        int                         nEnd;

        if (m_bIsRadioGroupStart)
        {
            //
            // We already have all information we need
            //
            nStart = nPos;
            nEnd   = m_vRadioGroup.m_nEnd;
        }
        else // next radio group item
        {
            //
            // Get the radio group end from the start item
            //
            nStart = m_vRadioGroup.m_nStart;
            nEnd = rItems.Item(nStart)->GetData()->m_vRadioGroup.m_nEnd;
        }

        //
        // Also uncheck all the other items in this radio group
        //
        wxMenuItemList::compatibility_iterator node = rItems.Item(nStart);

        for (int n = nStart; n <= nEnd && node; n++)
        {
            if (n == nPos)
            {
                ::WinSendMsg( hMenu
                             ,MM_SETITEMATTR
                             ,MPFROM2SHORT(n, TRUE)
                             ,MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED)
                            );
            }
            if (n != nPos)
            {
                node->GetData()->m_isChecked = FALSE;
                ::WinSendMsg( hMenu
                             ,MM_SETITEMATTR
                             ,MPFROM2SHORT(n, TRUE)
                             ,MPFROM2SHORT(MIA_CHECKED, FALSE)
                            );
            }
            node = node->GetNext();
        }
    }
    else // check item
    {
        if (bCheck)
            bOk = (bool)::WinSendMsg( hMenu
                                     ,MM_SETITEMATTR
                                     ,MPFROM2SHORT(GetRealId(), TRUE)
                                     ,MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED)
                                    );
        else
            bOk = (bool)::WinSendMsg( hMenu
                                     ,MM_SETITEMATTR
                                     ,MPFROM2SHORT(GetRealId(), TRUE)
                                     ,MPFROM2SHORT(MIA_CHECKED, FALSE)
                                    );
    }
    if (!bOk)
    {
        wxLogLastError(wxT("CheckMenuItem"));
    }
    wxMenuItemBase::Check(bCheck);
} // end of wxMenuItem::Check
Beispiel #10
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 #11
0
void wxMenuItem::Check(bool check)
{
    wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );

    if ( m_isChecked == check )
        return;

    if ( m_parentMenu )
    {
        int flags = check ? MF_CHECKED : MF_UNCHECKED;
        HMENU hmenu = GetHMenuOf(m_parentMenu);

        if ( GetKind() == wxITEM_RADIO )
        {
            // it doesn't make sense to uncheck a radio item -- what would this
            // do?
            if ( !check )
                return;

            // get the index of this item in the menu
            const wxMenuItemList& items = m_parentMenu->GetMenuItems();
            int pos = items.IndexOf(this);
            wxCHECK_RET( pos != wxNOT_FOUND,
                         wxT("menuitem not found in the menu items list?") );

            // get the radio group range
            int start,
                end;

            if ( !m_parentMenu->MSWGetRadioGroupRange(pos, &start, &end) )
            {
                wxFAIL_MSG( wxT("Menu radio item not part of radio group?") );
                return;
            }

#ifdef __WIN32__
            // calling CheckMenuRadioItem() with such parameters hangs my system
            // (NT4 SP6) and I suspect this could happen to the others as well,
            // so don't do it!
            wxCHECK_RET( start != -1 && end != -1,
                         wxT("invalid ::CheckMenuRadioItem() parameter(s)") );

            if ( !::CheckMenuRadioItem(hmenu,
                                       start,   // the first radio group item
                                       end,     // the last one
                                       pos,     // the one to check
                                       MF_BYPOSITION) )
            {
                wxLogLastError(wxT("CheckMenuRadioItem"));
            }
#endif // __WIN32__

            // also uncheck all the other items in this radio group
            wxMenuItemList::compatibility_iterator node = items.Item(start);
            for ( int n = start; n <= end && node; n++ )
            {
                if ( n != pos )
                {
                    node->GetData()->m_isChecked = false;
                }

                node = node->GetNext();
            }
        }
        else // check item
        {
            if ( ::CheckMenuItem(hmenu,
                                 GetMSWId(),
                                 MF_BYCOMMAND | flags) == (DWORD)-1 )
            {
                wxFAIL_MSG(wxT("CheckMenuItem() failed, item not in the menu?"));
            }
        }
    }

    wxMenuItemBase::Check(check);
}
Beispiel #12
0
void wxMenuItem::DoSetBitmap(const wxBitmap& bmp, bool bChecked)
{
    if ( bChecked )
    {
        if ( m_bmpChecked.IsSameAs(bmp) )
            return;

        m_bmpChecked = bmp;
    }
    else
    {
        if ( m_bmpUnchecked.IsSameAs(bmp) )
            return;

        m_bmpUnchecked = bmp;
    }

#if wxUSE_OWNER_DRAWN
    // already marked as owner-drawn, cannot be reverted
    if ( IsOwnerDrawn() )
        return;

    if ( MSWMustUseOwnerDrawn() )
    {
        SetOwnerDrawn(true);

        // Parent menu has to be rearranged/recalculated in this case
        // (all other menu items have to be also set to owner-drawn mode).
        if ( m_parentMenu )
        {
            size_t pos;
            wxMenuItem *item = m_parentMenu->FindChildItem(GetMSWId(), &pos);
            if ( item )
            {
                wxCHECK_RET( item == this, wxS("Non unique menu item ID?") );

                m_parentMenu->Remove(this);
                m_parentMenu->Insert(pos, this);
            }
            //else: the item hasn't been inserted into the parent menu yet
        }
        return;
    }
#endif // wxUSE_OWNER_DRAWN

    // the item can be not attached to any menu yet and SetBitmap() is still
    // valid to call in this case and should do nothing else
    if ( !m_parentMenu )
        return;

    HMENU hMenu = GetHMenuOf(m_parentMenu);
    if ( !hMenu )
        return;

    const UINT id = GetMSWId();

    const UINT state = ::GetMenuState(hMenu, id, MF_BYCOMMAND);
    if ( state == (UINT)-1 )
        return;

    // update the bitmap of the native menu item
    // don't set hbmpItem for the checkable items as it would
    // be used for both checked and unchecked state
    WinStruct<MENUITEMINFO> mii;
    if ( IsCheckable() )
    {
        mii.fMask = MIIM_CHECKMARKS;
        mii.hbmpChecked = GetHBitmapForMenu(true);
        mii.hbmpUnchecked = GetHBitmapForMenu(false);
    }
    else
    {
        mii.fMask = MIIM_BITMAP;
        mii.hbmpItem = GetHBitmapForMenu();
    }

    if ( !::SetMenuItemInfo(hMenu, id, FALSE, &mii) )
    {
        wxLogLastError(wxT("SetMenuItemInfo"));
    }
}
Beispiel #13
0
void wxMenuItem::CreateItem (WXWidget menu, wxMenuBar * menuBar,
                             wxMenu * topMenu, size_t index)
{
    m_menuBar = menuBar;
    m_topMenu = topMenu;

    if (GetId() == -3)
    {
        // Id=-3 identifies a Title item.
        m_buttonWidget = (WXWidget) XtVaCreateManagedWidget
            (wxStripMenuCodes(m_text),
            xmLabelGadgetClass, (Widget) menu, NULL);
    }
    else if (!IsSeparator() && !m_subMenu)
    {
        wxString txt = m_text;

        if (m_text.IsEmpty())
        {
            wxASSERT_MSG(wxIsStockID(GetId()), wxT("A non-stock menu item with an empty label?"));
            txt = wxGetStockLabel(GetId(), wxSTOCK_WITH_ACCELERATOR|wxSTOCK_WITH_MNEMONIC);
        }

        wxString strName = wxStripMenuCodes(txt);
        if (IsCheckable())
        {
            m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (strName,
                xmToggleButtonGadgetClass, (Widget) menu,
#ifdef XmNpositionIndex
                XmNpositionIndex, index,
#endif
                NULL);
            XtVaSetValues ((Widget) m_buttonWidget, XmNset, (Boolean) IsChecked(), NULL);
        }
        else
            m_buttonWidget = (WXWidget) XtVaCreateManagedWidget (strName,
            xmPushButtonGadgetClass, (Widget) menu,
#ifdef XmNpositionIndex
            XmNpositionIndex, index,
#endif
            NULL);
        char mnem = wxFindMnemonic (m_text);
        if (mnem != 0)
            XtVaSetValues ((Widget) m_buttonWidget, XmNmnemonic, mnem, NULL);

        //// TODO: proper accelerator treatment. What does wxFindAccelerator
        //// look for?
        strName = m_text;
        char *accel = wxFindAccelerator (strName);
        if (accel)
            XtVaSetValues ((Widget) m_buttonWidget, XmNaccelerator, accel, NULL);

        // TODO: What does this do?
        XmString accel_str = wxFindAcceleratorText (strName);
        if (accel_str)
        {
            XtVaSetValues ((Widget) m_buttonWidget, XmNacceleratorText, accel_str, NULL);
            XmStringFree (accel_str);
        }

        if (IsCheckable())
            XtAddCallback ((Widget) m_buttonWidget,
            XmNvalueChangedCallback,
            (XtCallbackProc) wxMenuItemCallback,
            (XtPointer) this);
        else
            XtAddCallback ((Widget) m_buttonWidget,
            XmNactivateCallback,
            (XtCallbackProc) wxMenuItemCallback,
            (XtPointer) this);
        XtAddCallback ((Widget) m_buttonWidget,
            XmNarmCallback,
            (XtCallbackProc) wxMenuItemArmCallback,
            (XtPointer) this);
        XtAddCallback ((Widget) m_buttonWidget,
            XmNdisarmCallback,
            (XtCallbackProc) wxMenuItemDisarmCallback,
            (XtPointer) this);
    }
    else if (IsSeparator())
    {
        m_buttonWidget = (WXWidget) XtVaCreateManagedWidget ("separator",
            xmSeparatorGadgetClass, (Widget) menu,
#ifndef XmNpositionIndex
            XmNpositionIndex, index,
#endif
            NULL);
    }
    else if (m_subMenu)
    {
        m_buttonWidget = m_subMenu->CreateMenu (menuBar, menu, topMenu, index, m_text, true);
        m_subMenu->SetButtonWidget(m_buttonWidget);
        XtAddCallback ((Widget) m_buttonWidget,
            XmNcascadingCallback,
            (XtCallbackProc) wxMenuItemArmCallback,
            (XtPointer) this);
    }
    if (m_buttonWidget)
        XtSetSensitive ((Widget) m_buttonWidget, (Boolean) IsEnabled());
}