[vtkusers] Re: Can't catch double clicks in vtkWin32RenderWindowInteractor
list at kobenetz.de
list at kobenetz.de
Thu Mar 22 04:30:14 EDT 2007
> list at kobenetz.de wrote:
>> VTK 5.0.2, WinXP SP2 on Mac(Intel) with Bootcamp, C++, Visual Studio
>> 2005
>>
>> Hi,
>>
>> I'm having some trouble with the vtkWin32RenderWindowInteractor and the
>> mouse:
>>
>> 1. I can't catch double-clicks
>> 2. The mouse-picking as described in
>> http://www.vtk.org/Wiki/VTK_Mouse_Picking does not work for me. See
>> description below.
>>
>>
>> 1. I've tried using vtkRenderWindowInteractor::GetRepeatCount() with the
>> Default style and the TrackballCamera style. GetRepeatCount does never
>> return 1.
>>
>> I've looked through the source and traced back the problem to the
>> following file and inserted two 'printf's to see if the clicks are
>> beeing
>> caught:
>>
>> vtkWin32RenderWindowInteractor.cxx:
>> ---- Line 640
>>
>> case WM_LBUTTONDBLCLK:
>> me->OnLButtonDown(hWnd,wParam,MAKEPOINTS(lParam).x,MAKEPOINTS(lParam).y,
>> 1);
>> printf ("\n\nDouble-click!\n\n");
>> break;
>>
>> case WM_LBUTTONDOWN:
>> me->OnLButtonDown(hWnd,wParam,MAKEPOINTS(lParam).x,MAKEPOINTS(lParam).y,
>> 0);
>> printf ("\n\nSingle-click!\n\n");
>> break;
>>
>> ----
>>
>> When I double-click the mouse in the RenderWindow I get the
>> "Single-click"
>> message twice, not the "Double-click" one. Where's the problem?
>>
>>
>> 2. When trying to use the mouse picking as described, "press"-"don't
>> move"-"release" it always appears that the mouse has been moved in
>> between:
>>
>>
>> ----
>> void cb_leftButtonDown( vtkObject *caller, unsigned long eid, void
>> *clientdata, void *calldata )
>> {
>> MouseMotion = 0;
>> cout << "cb_leftButtonDown\n";
>>
>> if( iren->GetRepeatCount() == 1 )
>> {
>> // This never happens anyway ...
>> cout << "Double-click!\n";
>> }
>>
>> style->OnLeftButtonDown();
>> }
>>
>> void cb_leftButtonUp( vtkObject *caller, unsigned long eid, void
>> *clientdata, void *calldata )
>> {
>>
>> cout << "cb_leftButtonUp\n";
>>
>> if( MouseMotion == 0 )
>> {
>> picker->Pick( iren->GetEventPosition()[0],
>> iren->GetEventPosition()[1],
>> 0.0, ren1);
>> showPick( 0,0,0,0 ); // Draw some info about picking location ...
>> }
>>
>> style->OnLeftButtonUp();
>> }
>>
>> void cb_mouseMove( vtkObject *caller, unsigned long eid, void
>> *clientdata,
>> void *calldata )
>> {
>> if( MouseMotion == 0 )
>> {
>> cout << "Mouse has been moved!";
>> }
>> MouseMotion = 1;
>>
>> style->OnMouseMove();
>> }
>> ----
>>
>> What happens is the following: I click and hold the mouse button without
>> moving the mouse (Optical mouse up in the air). Instantly I get the
>> Message "cb_leftButtonDown" and a few MILLISECONS later "Mouse has been
>> moved!". If I click-release fast enough I can manage to get a pick, but
>> why do I get this unexpected behaviour?
>>
>> Thanks,
>>
>> Christoph
>
> Hi Christoph,
>
> The RepeatCount will only be set when you've released the button, so
> should be accessed in your cb_leftButtonUp method...
Nope. Look at the vtk code. The exact opposite is the case: After a
ButtonRelease event the RepeatCount will ALWAYS be 0:
----vtkWin32RenderWindowInteractor.cxx:
void vtkWin32RenderWindowInteractor::OnLButtonDown(HWND wnd,UINT nFlags,
int X, int Y, int repeat)
{
if (!this->Enabled)
{
return;
}
SetCapture(wnd);
this->SetEventInformationFlipY(X,
Y,
nFlags & MK_CONTROL,
nFlags & MK_SHIFT,
0, repeat); /* HERE repeat is set */
this->InvokeEvent(vtkCommand::LeftButtonPressEvent,NULL);
}
void vtkWin32RenderWindowInteractor::OnLButtonUp(HWND,UINT nFlags,
int X, int Y)
{
if (!this->Enabled)
{
return;
}
this->SetEventInformationFlipY(X,
Y,
nFlags & MK_CONTROL,
nFlags & MK_SHIFT); /* HERE repeat is not
set and defaults to 0 */
this->InvokeEvent(vtkCommand::LeftButtonReleaseEvent,NULL);
ReleaseCapture( );
}
----
----vtkWin32RenderWindowInteractor.h:
// Description:
// Set all the event information in one call.
void SetEventInformation(int x,
int y,
int ctrl=0,
int shift=0,
char keycode=0,
int repeatcount=0,
const char* keysym=0)
{
this->LastEventPosition[0] = this->EventPosition[0];
this->LastEventPosition[1] = this->EventPosition[1];
this->EventPosition[0] = x;
this->EventPosition[1] = y;
this->ControlKey = ctrl;
this->ShiftKey = shift;
this->KeyCode = keycode;
this->RepeatCount = repeatcount;
if(keysym)
{
this->SetKeySym(keysym);
}
this->Modified();
}
----
>
> if( MouseMotion == 0 && iren->GetRepeatCount() == 1)
> {
> ...
> }
>
> Have you cut out where you declare the "iren" and "style" pointers in
> your callback?
> You'll have to cast "caller" as a pointer to vtkInteractorStyle and call:
Anyway, the code-modification I did with the
printf("\n\nDouble-Click\n\n"); above is independent of any vtk-callback.
How could vtk know about a double-click when the win32 WM_LBUTTONDBLCLK
event is never fired? My question is: What does prevent the
WM_LBUTTONDBLCLK-event?
> vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(caller);
> vtkRenderWindowInteractor *iren = style->GetInteractor();
>
> I've only tried this code with Tcl scripts (and the modified C++
> classes)... there could be a bug with the win32 events.
>
> hth
>
> Goodwin
Christoph
More information about the vtkusers
mailing list