Search code examples
c++wxwidgets

wxRibbonButtonBar : Changing a Button's Image at Runtime


I was looking for a better way to change the image of a button on a wxRibbonButtonBar at runtime. In MS Excel when the background of a cell or cells change, the ribbon button reflects the last selected color. Therefore, my goal is to achieve something similar. I thought of two possible approaches:

The first approach: there are two functions:

1) AddButton (int button_id,..,const wxBitmap &bitmap,...)

2) DeleteButton (int button_id)

Since the ID of the button will be known, I was thinking of calling the DeleteButton and then calling AddButton whenever I need to change the bitmap. Although this will work, I suspect this is a good approach.

The other possible approach: Since the AddButton function returns a pointer to wxRibbonButtonBarButtonBase and there is the following function

void SetItemClientData (wxRibbonButtonBarButtonBase *item, void *data)

to which the return value, wxRibbonButtonBarButtonBase, can be passed as an argument to point to specific button. However, here, I am not sure what argument data exactly refers to (since a button can have a title, bitmap etc...) and how I can pass wxBitmap to this function as a data.

The following code works, which is a mix of the 1st and 2nd approaches, much more of 1st; however, I doubt it is the optimal way.

wxColourDialog dlg(this);

wxColour color;
if (dlg.ShowModal() == wxID_OK) color = dlg.GetColourData().GetColour(); else return;

wxMemoryDC dc;
wxBitmap bmp(bucket_xpm); //32 by 32
dc.SelectObject(bmp);
dc.SetBrush(color);
dc.DrawRectangle(0, 28, 32, 32);

int itemID=m_ribbonButtonBarFormat->GetItemId(m_BtnFillColor);
m_ribbonButtonBarFormat->DeleteButton(itemID);
m_BtnFillColor=m_ribbonButtonBarFormat->AddButton(itemID, wxT("Fill Color"), bmp, wxEmptyString);
m_ribbonButtonBarFormat->Realize();

Any ideas would be appreciated and if this is in favor of the 2nd approach a code snippet would be of great help.


Solution

  • My goal has been "I was looking for a better way to change the image of a button on a wxRibbonButtonBar at runtime. In MS Excel when the background of a cell or cells change, the ribbon button reflects the last selected color."

    The downside of my approach was I was aiming to change the bitmap of wxRibbonButtonBar. As a matter of fact, Excel achieves this with hybrid button tool which when clicked on the dropdown tool it shows the color palette and then once you click on the button, it applies the selected color (I still dont know how to show a floating color palette though).

    Therefore, I changed my approach from wxRibbonButtonBar to wxRibbonToolBar and added a hybrid button with the following code:

    m_ribbonToolBarFormat->AddHybridTool(ID_FORMATFILLCOLOR, bmp, wxT("Fill Color"));
    

    Hybrid tool can generate two events: 1) OnRibbonToolClicked 2) OnRibbonToolDropdownClicked

    OnRibbonToolDropdownFillColorClicked(wxRibbonToolBarEvent& event)
    {
        wxColourDialog dlg(this);
    
        if (dlg.ShowModal() == wxID_OK) m_LastChosenFillColor = dlg.GetColourData().GetColour(); else return;
    
        wxMemoryDC dc;
        wxBitmap bmp(bucket_xpm);
        dc.SelectObject(bmp);
        dc.SetBrush(m_LastChosenFillColor);
        dc.DrawRectangle(0, 28, 32, 32);
    
        m_ribbonToolBarFormat->SetToolNormalBitmap(ID_FORMATFILLCOLOR, bmp);
        m_ribbonToolBarFormat->Refresh();
    

    With SetToolNormalBitmap, I can without deleting the tool can set the image of the tool at run-time.