wxToolbarItem is disabled and doesn't respond to mouse click events

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
Ron_new
Experienced Solver
Experienced Solver
Posts: 50
Joined: Thu Mar 20, 2014 9:53 am

wxToolbarItem is disabled and doesn't respond to mouse click events

Post by Ron_new »

Hi,

I use the wxWidgets controls in C:B 13.12 (wxSmit 2.8.12) and create the wxToolbar and wxToolbarItem with the following code:

Code: Select all

    ToolBar1 = new wxToolBar(this, ID_TOOLBAR1, wxDefaultPosition, wxDefaultSize, wxTB_HORIZONTAL|wxNO_BORDER, _T("ID_TOOLBAR1"));
    ToolBarItem1 = ToolBar1->AddTool(ID_TOOLBARITEM1, _("New item"), wxArtProvider::GetBitmap(wxART_MAKE_ART_ID_FROM_STR(_T("wxART_HARDDISK")),wxART_TOOLBAR), wxNullBitmap, wxITEM_NORMAL, wxEmptyString, wxEmptyString);

    ToolBar1->Realize();
    SetToolBar(ToolBar1);
    //ToolBar1->EnableTool(ToolBarItem1,true);
ToolbarItem1 is showing up on the tool bar palette but doesn't respond the user clicks, I also noticed that If I hoover over the toolbar button I didn't get the color change which notifies that mouse cursor is over toolbutton which change it to blueish color.

How am I supposed to diagnose this?
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxToolbarItem is disabled and doesn't respond to mouse click events

Post by doublemax »

The code you posted works fine for me under Windows.

Which platform are you on?
Is there a particular reason you're using the very outdated wxWidgets version 2.8.12?
Does the "toolbar" sample work for you?
Use the source, Luke!
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxToolbarItem is disabled and doesn't respond to mouse click events

Post by ONEEYEMAN »

Hi,
Do you have a click handler connected somewhere?
Is your application an MDI or dock/view?

It is possible that you have a wxWindow covering the toolbar even so it is visible.

Thank you.
Ron_new
Experienced Solver
Experienced Solver
Posts: 50
Joined: Thu Mar 20, 2014 9:53 am

Re: wxToolbarItem is disabled and doesn't respond to mouse click events

Post by Ron_new »

Sorry for the late response, It took me a while when I tried to familiarize myself with wxWidgets, which is still on going process.
s there a particular reason you're using the very outdated wxWidgets version 2.8.12?
I was having 2 versions wxWidgets 2.8.12 and 3.0.1 which was configured and working properly so that's why I used them, now I totally skip 2.8.12 and use 3.0.1 now. Soon I'll try to port to more recent version 3.1.0.

Back to my case, actually I was implementing renering loop, I followed the instructions given here https://wiki.wxwidgets.org/Making_a_render_loop) now it works (onIdle implementation) to some extent: I have 2 descrepancy :

#1) First is when I try to resize the Form (derived from wxFrame) the whole screen freezes and doesn't respond to mouse events(that even freezes the Code::Blocks IDE), since "render loop article" doesn't reflect the how to cope with onSize event, I assumed that I should be implementing the event handle of wxFrame or BasisDrawPane, but even after that the result is same, how can I overcome that?

#2) Any control laying in the form never gets renderer i.e. buttons, CtrlTree etc.. Should I be using Sizers as container for them ?

Code: Select all

void wxWidgets_ToolbarFrame::OnSize(wxSizeEvent& event)
{
    Refresh();
    event.Skip();
}
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxToolbarItem is disabled and doesn't respond to mouse click events

Post by doublemax »

I think we need to see more code.

Do you really need a rendering loop? What exactly are you trying to do?
First is when I try to resize the Form (derived from wxFrame) the whole screen freezes and doesn't respond to mouse events
Assuming you're under Windows, the most likely reason for this is that you have a custom paint event handler somewhere, but don't create a wxPaintDC inside it.
Any control laying in the form never gets renderer i.e. buttons, CtrlTree etc.. Should I be using Sizers as container for them ?
Using sizers is of course recommended and preferable, but it doesn't explain this problem.

Code: Select all

void wxWidgets_ToolbarFrame::OnSize(wxSizeEvent& event)
{
    Refresh();
    event.Skip();
}
This is not needed, the same can be achieved by setting the wxFULL_REPAINT_ON_RESIZE style flag when creating the frame.
Use the source, Luke!
Ron_new
Experienced Solver
Experienced Solver
Posts: 50
Joined: Thu Mar 20, 2014 9:53 am

Re: wxToolbarItem is disabled and doesn't respond to mouse click events

Post by Ron_new »

Yes I'm on windows platform Win8.1 x64 - minGW 4.7.1

Rendering loop is from graphic engine namely OpenSceneGraph 3.4 version, here is the code :

After your post I noticed that I've created the OnIdle event handler of WxWidgetFrame(derived from wxFrame) not the intended one wxApp as aritcle instructs. I'll change that but, for the time being app has some nuisance global variables which I have to sort out, beforehand.

For sake consitency I 'll attach the unmodified source code, later on I'll report the progress.

Code: Select all

void WidgetInitializeOSG(HWND win_handle)
{
   root_node = new osg::Group;
    // RUBBER LINE DEFINITIONS
    rubber_line = new osg::Geometry;
    rubber_line->setName("Rubber Line");
    osg::Vec3Array *vers = new osg::Vec3Array(2);
    (*vers)[0] = osg::Vec3d(0,0,0);
    (*vers)[1] = osg::Vec3d(0,10,0);

    rubber_line->setVertexArray(vers);
    rubber_line->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES,0,2));
    osg::ref_ptr<osg::Geode> gode= new osg::Geode;
    gode->addDrawable(rubber_line);
    root_node->addChild(gode);

    draw_rubber = true;

    hud_text = new osgText::Text;
    PAT = new osg::PositionAttitudeTransform;

    // CREATE DEVICE CONTEXT
    HWND frame_wnd = win_handle; //HWND( wxWidgets_ToolbarFrame::GetHandle() ); ORIGINAL CODE

    osg::ref_ptr<osgFX::Outline> outline = new osgFX::Outline;
    outline->setWidth( 8 );
    outline->setColor( osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) );

    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;

    traits->x = 0;
    traits->y = 0;
    traits->width = 800;
    traits->height = 600;
    traits->windowDecoration = false;
    traits->doubleBuffer = true;
    //traits->inheritedWindowData = windata;
    traits->inheritedWindowData = new osgViewer::GraphicsWindowWin32::WindowData(win_handle);
    traits->setInheritedWindowPixelFormat = true;
    traits->sharedContext = NULL;
    traits->supportsResize = true;

    RECT rect;
    ::GetWindowRect(frame_wnd,&rect );

    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext( traits.get() );
    g_viewer->getCamera()->setGraphicsContext( gc.get());

    g_viewer->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );
    g_viewer->getCamera()->setProjectionMatrixAsPerspective( 60.0f,(double)traits->width/(double)traits->height,1.0,10000.0 );
    root = new osg::Geode;
    osg::ref_ptr<osg::ShapeDrawable> shape1 = new osg::ShapeDrawable;
    shape1->setShape( new osg::Box(osg::Vec3(-3.0f, 0.0f, 0.0f), 2.0f, 2.0f, 1.0f) );

    g_viewer->getCamera()->setClearMask(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("D:/../OpenSceneGraph-Data-3.0.0/cessna.osgt");
    root_node->addChild(loadedModel);

    int num_child = root_node->getNumChildren();
    g_viewer->setSceneData( root_node);
    //g_viewer->setKeyEventSetsDone( 0 );
    g_viewer->setCameraManipulator( new osgGA::OrbitManipulator );
    g_viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);

    osgViewer::CompositeViewer::Windows wins;
    g_viewer->getWindows(wins);
}

//////////////////

BasicDrawPane::BasicDrawPane(wxFrame* parent) :wxPanel(parent)
{

}

void BasicDrawPane::OnSize(wxSizeEvent& event)
{
    Refresh();
    event.Skip();
}

void BasicDrawPane::paintEvent(wxPaintEvent& evt)
{
    wxPaintDC dc(this);
    //render(dc);
    while ( !g_viewer->done() )
    {
        g_viewer->frame();
        wxYield();
    }
}

void BasicDrawPane::paintNow()
{
    wxClientDC dc(this);
    render(dc);
}

void BasicDrawPane::render( wxDC& dc )
{
    static int y = 0;
    static int y_speed = 2;

    y += y_speed;
    if(y<0) y_speed = 2;
    if(y>200) y_speed = -2;

    dc.SetBackground( *wxWHITE_BRUSH );
    dc.Clear();
    dc.DrawText(wxT("Testing"), 40, y);
}

wxWidgets_ToolbarFrame::wxWidgets_ToolbarFrame(wxWindow* parent,wxWindowID id)
{
........
......
... Code Omitted here 

  wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);

    drawPane = new BasicDrawPane( this );
    sizer->Add(drawPane, 1, wxEXPAND);

    WidgetInitializeOSG(drawPane->GetHandle());
    this->SetSizer(sizer);
    this->Show();
}

Attachments
wxWidgets_ToolbarMain.cpp
(17.49 KiB) Downloaded 80 times
wxWidgets_ToolbarApp.h
(550 Bytes) Downloaded 85 times
wxWidgets_ToolbarApp.cpp
(972 Bytes) Downloaded 93 times
Ron_new
Experienced Solver
Experienced Solver
Posts: 50
Joined: Thu Mar 20, 2014 9:53 am

Re: wxToolbarItem is disabled and doesn't respond to mouse click events

Post by Ron_new »

The header which didn't uploaded
Attachments
wxWidgets_ToolbarMain.h
(2.78 KiB) Downloaded 42 times
User avatar
doublemax
Moderator
Moderator
Posts: 19158
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: wxToolbarItem is disabled and doesn't respond to mouse click events

Post by doublemax »

I couldn't test it because i don't have OSG installed, but after reading about it a little, i think the problem lies here:

Code: Select all

void BasicDrawPane::paintEvent(wxPaintEvent& evt)
{
    wxPaintDC dc(this);
    //render(dc);
    while ( !g_viewer->done() )
    {
        g_viewer->frame();
        wxYield();
    }
}
I assume the "while ( !g_viewer->done() )" creates an endless loop.

Try just this:

Code: Select all

void BasicDrawPane::paintEvent(wxPaintEvent& evt)
{
    wxPaintDC dc(this);
    g_viewer->frame();
}
Same goes for the idle event handler:

Code: Select all

void wxWidgets_ToolbarFrame::OnIdle(wxIdleEvent& event)
{
  g_viewer->frame();  // alternatively, call just drawPane->Refresh(); here
  event.RequestMore();
}
Use the source, Luke!
Post Reply