Search code examples
c++wxwidgets

Having trouble iterating over the right children to change their color


I'm looking to make a menu where there are more than one wxStaticTexts and when one of them is clicked it turns black and the rest are/revert back to being grey (if they were clicked before, otherwise they would just stay grey)

The problem is I usurped this code which works great for doing the first part, it turns the item that was clicked black, but it doesn't turn the rest back to grey. My attempt at a solution is in the else block. I haven't attempted anything else because I'm still figuring both C++ and WxWidgets out and I still don't have a complete understanding of some concepts used in this snippet.

void MyFrame::OnMenuTxtBtnLeftClickPanel(wxMouseEvent& event) {

wxObject* obj = event.GetEventObject();
wxPanel* objPanel = ((wxPanel*)obj);
wxWindowList objChild = objPanel->GetChildren();

    for (wxWindowList::iterator it = objChild.begin(); it != objChild.end(); it++) {

        wxStaticText* aStaticText = dynamic_cast<wxStaticText*>(*it);

        if (aStaticText) {
            aStaticText->SetForegroundColour(wxColour("#000000"));
        }
        else {
            // Doesn't do anything when compiled
            // it should change the StaticTexts that weren't clicked back to grey
            dynamic_cast<wxStaticText*>(*it)->SetForegroundColour(wxColour("#C8C6C6"));
        }

    }


Solution

  • This works for me:

    void MyFrame::OnMenuTxtBtnLeftClickPanel(wxMouseEvent& event)
    {
        wxWindow* cur = wxDynamicCast(event.GetEventObject(),wxWindow);
        wxColor fg = m_panel1->GetForegroundColour();
    
        wxWindowList& children = m_panel1->GetChildren();
    
        for ( auto it = children.begin() ; it != children.end() ; ++it )
        {
            wxWindow* win = *it;
            if ( wxDynamicCast(win, wxStaticText) )
            {
                if ( win == cur )
                {
                    win->SetForegroundColour(wxColour("#000000"));
                }
                else
                {
                    win->SetForegroundColour(fg);
                }
            }
        }
    }
    

    In this code, m_panel1 is a wxPanel that is the parent of all the static texts.

    On GTK, it looks like this:

    animated gif if static texts changing color when clicked

    The handler was bound to each static text control in the frame constructor like this:

        m_staticText1->Bind(wxEVT_LEFT_UP,&MyFrame::OnMenuTxtBtnLeftClickPanel,this);
        m_staticText2->Bind(wxEVT_LEFT_UP,&MyFrame::OnMenuTxtBtnLeftClickPanel,this);
        m_staticText3->Bind(wxEVT_LEFT_UP,&MyFrame::OnMenuTxtBtnLeftClickPanel,this);
        m_staticText4->Bind(wxEVT_LEFT_UP,&MyFrame::OnMenuTxtBtnLeftClickPanel,this);
    

    m_staticText1, etc. should be changed to the names you're using for the text controls.