Reputation: 391
I have a window with a GLCanvas and scroll bars, I want the canvas to capture scroll events and forward them to the scroll bars, which are then used to position the 'camera.' So I've done this:
MainWindow::MainWindow(wxWindow* parent,wxWindowID id)
{
//...
GlCanvas->Connect(ID_GLCANVAS1, wxEVT_MOUSEWHEEL, (wxObjectEventFunction)&MainWindow::onMouseWheel, 0L, this);
}
void MainWindow::onMouseWheel(wxMouseEvent & event)
{
if(event.GetWheelAxis() == wxMOUSE_WHEEL_VERTICAL)
{
std::cerr << "vertical scroll" << std::endl;
verticalScroll->ProcessWindowEvent(event);
}
else
{
std::cerr << "horizontal scroll" << std::endl;
horizontalScroll->ProcessWindowEvent(event);
}
}
However, this isn't doing anything aside from the printouts. What do I do to get the scrollbars to process the wheel events?
============== Solution ==============
void MainWindow::onMouseWheel(wxMouseEvent & event)
{
event.Skip();
double rotation = ((double) event.GetWheelRotation()) / event.GetWheelDelta();
wxScrollBar * scrollBar;
double * delta;
if(event.GetWheelAxis() == wxMOUSE_WHEEL_VERTICAL)
{
scrollBar = verticalScroll;
delta = &verticalDelta;
rotation *= -1;
}
else
{
scrollBar = horizontalScroll;
delta = &horizontalDelta;
}
if(event.IsPageScroll())
{
rotation *= scrollBar->GetPageSize();
}
else
{
if(event.GetWheelAxis() == wxMOUSE_WHEEL_VERTICAL)
{
rotation *= event.GetLinesPerAction();
}
else
{
rotation *= event.GetColumnsPerAction();
}
}
*delta += rotation;
int scroll = scrollBar->GetThumbPosition();
int ds = (int) *delta;
*delta -= ds;
scroll += ds;
if(scroll < 0)
{
*delta = 0;
scroll = 0;
}
else if(scroll > scrollBar->GetRange())
{
*delta = 0;
scroll = scrollBar->GetRange();
}
scrollBar->SetThumbPosition(scroll);
}
Upvotes: 1
Views: 622
Reputation: 22678
You can't forward wx events to native controls, if you think about it, how would it be possible for this to work when the native controls don't have any idea about wx? Native controls generate native events which are then translated to wx events and given to your application, but nothing happens, or even can be really done, in the other direction.
In this particular case you can (relatively) easily translate scroll events to the calls to ScrollLines()
, ScrollPages()
or just SetScrollPos()
. This will allow you to control another window scrolling using the same scrollbar.
Do not forget to call Skip()
in the original handler to let the window being scrolled from actually scrolling too.
Upvotes: 1
Reputation: 7198
You need to conect()
, or better bind()
if your wx version allows it, a wxScrollEvent
If you choose to handle all scroll events by using wxEVT_COMMAND_SCROLL or wxEVT_SCROLL then you can get the type of event from the event parameter in your handler function.
Currently (wx 3.1) still there's no wxEVT_COMMAND_SCROLL nor wxEVT_SCROLL. Only partial definitions (page up, thumtrack, etc). It seems a bug. But you can use EVT_SCROLL in the old BEGIN_EVENT_TABLE/END_EVENT_TABLE way.
Upvotes: 0