Loading files
// Created on: 2012-05-28
//
// Copyright (c) 2011-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
// prevent disabling some MSVC warning messages by VTK headers
#include <Standard_WarningsDisable.hxx>
#ifdef _WIN32
#include <vtkWin32RenderWindowInteractor.h>
#include <vtkWin32OpenGLRenderWindow.h>
#else
#include <GL/glx.h>
// Preventing naming collisions between
// GLX and VTK versions 9.0 and above
#ifdef AllValues
#undef AllValues
#endif
// Resolve name collisions with X11 headers
#ifdef Status
#undef Status
#endif
#ifdef Success
#undef Success
#endif
#include <vtkXRenderWindowInteractor.h>
#include <vtkXOpenGLRenderWindow.h>
#endif
#include <vtkActor.h>
#include <vtkActorCollection.h>
#include <vtkCommand.h>
#include <vtkObjectFactory.h>
#include <vtkSmartPointer.h>
#include <Standard_WarningsRestore.hxx>
#include <IVtkDraw_Interactor.hxx>
#include <IVtkTools_ShapePicker.hxx>
#include <IVtkTools_SubPolyDataFilter.hxx>
#include <IVtkTools_DisplayModeFilter.hxx>
#include <IVtkTools_ShapeObject.hxx>
#include <IVtkTools_ShapeDataSource.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
//=================================================================================================
static void ClearHighlightAndSelection(const occ::handle<ShapePipelineMap>& theMap,
const bool doHighlighting,
const bool doSelection)
{
if (!doHighlighting && !doSelection)
{
return;
}
for (ShapePipelineMap::Iterator anIt(*theMap); anIt.More(); anIt.Next())
{
const occ::handle<IVtkDraw_HighlightAndSelectionPipeline>& aPL = anIt.Value();
if (doHighlighting)
{
aPL->ClearHighlightFilters();
}
if (doSelection)
{
aPL->ClearSelectionFilters();
}
}
}
vtkStandardNewMacro(IVtkDraw_Interactor)
//=================================================================================================
IVtkDraw_Interactor::IVtkDraw_Interactor()
:
#ifdef _WIN32
myWindowId(NULL),
myMouseInWindow(0)
#else
myIsLeftButtonPressed(false)
#endif
{
}
//=================================================================================================
IVtkDraw_Interactor::~IVtkDraw_Interactor() = default;
//=================================================================================================
void IVtkDraw_Interactor::SetShapePicker(const PSelector& theSelector)
{
mySelector = theSelector;
}
//=================================================================================================
void IVtkDraw_Interactor::SetPipelines(const occ::handle<ShapePipelineMap>& thePipelines)
{
myPipelines = thePipelines;
}
//=================================================================================================
void IVtkDraw_Interactor::SetOCCWindow(const occ::handle<Aspect_Window>& theWindow)
{
myWindow = theWindow;
}
//=================================================================================================
const occ::handle<Aspect_Window>& IVtkDraw_Interactor::GetOCCWindow() const
{
return myWindow;
}
//=================================================================================================
bool IVtkDraw_Interactor::IsEnabled() const
{
return (Enabled != 0);
}
//=================================================================================================
void IVtkDraw_Interactor::Initialize()
{
// Make sure we have a RenderWindow and camera
if (!this->RenderWindow)
{
vtkErrorMacro(<< "No renderer defined!");
return;
}
if (this->Initialized)
{
return;
}
this->Initialized = 1;
// Get the info we need from the RenderingWindow
int* aSize;
#ifdef _WIN32
vtkWin32OpenGLRenderWindow* aRenWin;
aRenWin = (vtkWin32OpenGLRenderWindow*)(this->RenderWindow);
aRenWin->Start();
aSize = aRenWin->GetSize();
aRenWin->GetPosition();
this->myWindowId = aRenWin->GetWindowId();
#else
vtkXOpenGLRenderWindow* aRenWin;
aRenWin = static_cast<vtkXOpenGLRenderWindow*>(this->RenderWindow);
this->myDisplayId = aRenWin->GetDisplayId();
this->myWindowId = aRenWin->GetWindowId();
aSize = aRenWin->GetSize();
aRenWin->Start();
#endif
this->Enable();
this->Size[0] = aSize[0];
this->Size[1] = aSize[1];
}
#ifdef _WIN32
LRESULT CALLBACK WndProc(HWND theHWnd, UINT theUMsg, WPARAM theWParam, LPARAM theLParam);
#endif
//=================================================================================================
void IVtkDraw_Interactor::Enable()
{
if (this->Enabled)
{
return;
}
// Add event handlers
#ifdef _WIN32
SetWindowLongPtr(this->myWindowId, GWLP_USERDATA, (LONG_PTR)this);
SetWindowLongPtr(this->myWindowId, GWLP_WNDPROC, (LONG_PTR)WndProc);
#else
Tcl_CreateFileHandler(ConnectionNumber(this->myDisplayId),
TCL_READABLE,
ProcessEvents,
(ClientData)this);
#endif
this->Enabled = 1;
this->Modified();
}
//=================================================================================================
void IVtkDraw_Interactor::MoveTo(int theX, int theY)
{
// Processing highlighting
mySelector->Pick(theX, theY, 0.0);
vtkSmartPointer<vtkActorCollection> anActorCollection = mySelector->GetPickedActors();
if (anActorCollection)
{
// Highlight picked subshapes
ClearHighlightAndSelection(myPipelines, true, false);
anActorCollection->InitTraversal();
while (vtkActor* anActor = anActorCollection->GetNextActor())
{
IVtkTools_ShapeDataSource* aDataSource = IVtkTools_ShapeObject::GetShapeSource(anActor);
if (!aDataSource)
{
continue;
}
IVtkOCC_Shape::Handle anOccShape = aDataSource->GetShape();
if (anOccShape.IsNull())
{
continue;
}
IVtk_IdType aShapeID = anOccShape->GetId();
occ::handle<Message_Messenger> anOutput = Message::DefaultMessenger();
if (!myPipelines->IsBound(aShapeID))
{
anOutput->SendWarning()
<< "Warning: there is no VTK pipeline registered for highlighted shape" << std::endl;
continue;
}
const occ::handle<IVtkDraw_HighlightAndSelectionPipeline>& aPL = myPipelines->Find(aShapeID);
// Add a subpolydata filter to the highlight pipeline for the shape data source.
IVtkTools_SubPolyDataFilter* aFilter = aPL->GetHighlightFilter();
// Set the selected sub-shapes ids to subpolydata filter.
NCollection_List<IVtk_IdType> aSubShapeIds = mySelector->GetPickedSubShapesIds(aShapeID);
// Get ids of cells for picked subshapes.
NCollection_List<IVtk_IdType> aSubIds;
NCollection_List<IVtk_IdType>::Iterator aMetaIds(aSubShapeIds);
for (; aMetaIds.More(); aMetaIds.Next())
{
NCollection_List<IVtk_IdType> aSubSubIds = anOccShape->GetSubIds(aMetaIds.Value());
aSubIds.Append(aSubSubIds);
}
aFilter->SetDoFiltering(!aSubIds.IsEmpty());
aFilter->SetData(aSubIds);
if (!aFilter->GetInput())
{
aFilter->SetInputConnection(aDataSource->GetOutputPort());
}
aFilter->Modified();
}
}
this->Render();
}
//=================================================================================================
void IVtkDraw_Interactor::OnSelection()
{
// Processing selection
vtkSmartPointer<vtkActorCollection> anActorCollection = mySelector->GetPickedActors();
if (anActorCollection)
{
// Highlight picked subshapes.
ClearHighlightAndSelection(myPipelines, false, true);
anActorCollection->InitTraversal();
while (vtkActor* anActor = anActorCollection->GetNextActor())
{
IVtkTools_ShapeDataSource* aDataSource = IVtkTools_ShapeObject::GetShapeSource(anActor);
if (!aDataSource)
{
continue;
}
IVtkOCC_Shape::Handle anOccShape = aDataSource->GetShape();
if (anOccShape.IsNull())
{
continue;
}
IVtk_IdType aShapeID = anOccShape->GetId();
occ::handle<Message_Messenger> anOutput = Message::DefaultMessenger();
if (!myPipelines->IsBound(aShapeID))
{
anOutput->SendWarning() << "Warning: there is no VTK pipeline registered for picked shape"
<< std::endl;
continue;
}
const occ::handle<IVtkDraw_HighlightAndSelectionPipeline>& aPL = myPipelines->Find(aShapeID);
// Add a subpolydata filter to the selection pipeline for the shape data source.
IVtkTools_SubPolyDataFilter* aFilter = aPL->GetSelectionFilter();
// Set the selected sub-shapes ids to subpolydata filter.
NCollection_List<IVtk_IdType> aSubShapeIds = mySelector->GetPickedSubShapesIds(aShapeID);
// Get ids of cells for picked subshapes.
NCollection_List<IVtk_IdType> aSubIds;
NCollection_List<IVtk_IdType>::Iterator aMetaIds(aSubShapeIds);
for (; aMetaIds.More(); aMetaIds.Next())
{
NCollection_List<IVtk_IdType> aSubSubIds = anOccShape->GetSubIds(aMetaIds.Value());
aSubIds.Append(aSubSubIds);
}
aFilter->SetDoFiltering(!aSubIds.IsEmpty());
aFilter->SetData(aSubIds);
if (!aFilter->GetInput())
{
aFilter->SetInputConnection(aDataSource->GetOutputPort());
}
aFilter->Modified();
}
}
this->Render();
}
#ifdef _WIN32
//=================================================================================================
void IVtkDraw_Interactor::OnMouseMove(HWND theHWnd, UINT theNFlags, int theX, int theY)
{
if (!this->Enabled)
{
return;
}
this->SetEventInformationFlipY(theX, theY, theNFlags & MK_CONTROL, theNFlags & MK_SHIFT);
this->SetAltKey(GetKeyState(VK_MENU) & (~1));
if (!this->myMouseInWindow
&& (theX >= 0 && theX < this->Size[0] && theY >= 0 && theY < this->Size[1]))
{
this->InvokeEvent(vtkCommand::EnterEvent, NULL);
this->myMouseInWindow = 1;
// request WM_MOUSELEAVE generation
TRACKMOUSEEVENT aTme;
aTme.cbSize = sizeof(TRACKMOUSEEVENT);
aTme.dwFlags = TME_LEAVE;
aTme.hwndTrack = theHWnd;
TrackMouseEvent(&aTme);
}
if (!(theNFlags & MK_LBUTTON))
this->MoveTo(theX, this->Size[1] - theY - 1);
this->InvokeEvent(vtkCommand::MouseMoveEvent, NULL);
}
//=================================================================================================
void IVtkDraw_Interactor::OnMouseWheelForward(HWND, UINT theNFlags, int theX, int theY)
{
if (!this->Enabled)
{
return;
}
this->SetEventInformationFlipY(theX, theY, theNFlags & MK_CONTROL, theNFlags & MK_SHIFT);
this->SetAltKey(GetKeyState(VK_MENU) & (~1));
this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, NULL);
}
//=================================================================================================
void IVtkDraw_Interactor::OnMouseWheelBackward(HWND, UINT theNFlags, int theX, int theY)
{
if (!this->Enabled)
{
return;
}
this->SetEventInformationFlipY(theX, theY, theNFlags & MK_CONTROL, theNFlags & MK_SHIFT);
this->SetAltKey(GetKeyState(VK_MENU) & (~1));
this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, NULL);
}
//=================================================================================================
void IVtkDraw_Interactor::OnLButtonDown(HWND theHWnd,
UINT theNFlags,
int theX,
int theY,
int theRepeat)
{
if (!this->Enabled)
{
return;
}
SetFocus(theHWnd);
SetCapture(theHWnd);
this->SetEventInformationFlipY(theX,
theY,
theNFlags & MK_CONTROL,
theNFlags & MK_SHIFT,
0,
theRepeat);
this->SetAltKey(GetKeyState(VK_MENU) & (~1));
OnSelection();
this->InvokeEvent(vtkCommand::LeftButtonPressEvent, NULL);
}
//=================================================================================================
void IVtkDraw_Interactor::OnLButtonUp(HWND, UINT theNFlags, int theX, int theY)
{
if (!this->Enabled)
{
return;
}
this->SetEventInformationFlipY(theX, theY, theNFlags & MK_CONTROL, theNFlags & MK_SHIFT);
this->SetAltKey(GetKeyState(VK_MENU) & (~1));
this->InvokeEvent(vtkCommand::LeftButtonReleaseEvent, NULL);
ReleaseCapture();
}
//=================================================================================================
void IVtkDraw_Interactor::OnMButtonDown(HWND theHWnd,
UINT theNFlags,
int theX,
int theY,
int theRepeat)
{
if (!this->Enabled)
{
return;
}
SetFocus(theHWnd);
SetCapture(theHWnd);
this->SetEventInformationFlipY(theX,
theY,
theNFlags & MK_CONTROL,
theNFlags & MK_SHIFT,
0,
theRepeat);
this->SetAltKey(GetKeyState(VK_MENU) & (~1));
this->InvokeEvent(vtkCommand::MiddleButtonPressEvent, NULL);
}
//=================================================================================================
void IVtkDraw_Interactor::OnMButtonUp(HWND, UINT theNFlags, int theX, int theY)
{
if (!this->Enabled)
{
return;
}
this->SetEventInformationFlipY(theX, theY, theNFlags & MK_CONTROL, theNFlags & MK_SHIFT);
this->SetAltKey(GetKeyState(VK_MENU) & (~1));
this->InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, NULL);
ReleaseCapture();
}
//=================================================================================================
void IVtkDraw_Interactor::OnRButtonDown(HWND theHWnd,
UINT theNFlags,
int theX,
int theY,
int theRepeat)
{
if (!this->Enabled)
{
return;
}
SetFocus(theHWnd);
SetCapture(theHWnd);
this->SetEventInformationFlipY(theX,
theY,
theNFlags & MK_CONTROL,
theNFlags & MK_SHIFT,
0,
theRepeat);
this->SetAltKey(GetKeyState(VK_MENU) & (~1));
this->InvokeEvent(vtkCommand::RightButtonPressEvent, NULL);
}
//=================================================================================================
void IVtkDraw_Interactor::OnRButtonUp(HWND, UINT theNFlags, int theX, int theY)
{
if (!this->Enabled)
{
return;
}
this->SetEventInformationFlipY(theX, theY, theNFlags & MK_CONTROL, theNFlags & MK_SHIFT);
this->SetAltKey(GetKeyState(VK_MENU) & (~1));
this->InvokeEvent(vtkCommand::RightButtonReleaseEvent, NULL);
ReleaseCapture();
}
//=================================================================================================
void IVtkDraw_Interactor::OnSize(HWND, UINT, int theX, int theY)
{
this->UpdateSize(theX, theY);
if (this->Enabled)
{
this->InvokeEvent(vtkCommand::ConfigureEvent, NULL);
}
}
//=================================================================================================
void IVtkDraw_Interactor::OnTimer(HWND, UINT theTimerId)
{
if (!this->Enabled)
{
return;
}
int aTid = static_cast<int>(theTimerId);
this->InvokeEvent(vtkCommand::TimerEvent, (void*)&aTid);
// Here we deal with one-shot versus repeating timers
if (this->IsOneShotTimer(aTid))
{
KillTimer(this->myWindowId, aTid); //'cause windows timers are always repeating
}
}
//=================================================================================================
LRESULT CALLBACK WndProc(HWND theHWnd, UINT theUMsg, WPARAM theWParam, LPARAM theLParam)
{
LRESULT aRes = 0;
IVtkDraw_Interactor* anInteractor = 0;
anInteractor = (IVtkDraw_Interactor*)GetWindowLongPtrW(theHWnd, GWLP_USERDATA);
if (anInteractor && anInteractor->GetReferenceCount() > 0)
{
anInteractor->Register(anInteractor);
aRes = ViewerWindowProc(theHWnd, theUMsg, theWParam, theLParam, anInteractor);
anInteractor->UnRegister(anInteractor);
}
return aRes;
}
//=================================================================================================
LRESULT CALLBACK ViewerWindowProc(HWND theHWnd,
UINT theMsg,
WPARAM theWParam,
LPARAM theLParam,
IVtkDraw_Interactor* theInteractor)
{
switch (theMsg)
{
case WM_CLOSE:
theInteractor->GetOCCWindow()->Unmap();
return 0;
case WM_PAINT:
theInteractor->Render();
break;
case WM_SIZE:
theInteractor->OnSize(theHWnd, (UINT)theWParam, LOWORD(theLParam), HIWORD(theLParam));
break;
case WM_LBUTTONDBLCLK:
theInteractor->OnLButtonDown(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y,
1);
break;
case WM_LBUTTONDOWN:
theInteractor->OnLButtonDown(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y,
0);
break;
case WM_LBUTTONUP:
theInteractor->OnLButtonUp(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y);
break;
case WM_MBUTTONDBLCLK:
theInteractor->OnMButtonDown(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y,
1);
break;
case WM_MBUTTONDOWN:
theInteractor->OnMButtonDown(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y,
0);
break;
case WM_MBUTTONUP:
theInteractor->OnMButtonUp(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y);
break;
case WM_RBUTTONDBLCLK:
theInteractor->OnRButtonDown(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y,
1);
break;
case WM_RBUTTONDOWN:
theInteractor->OnRButtonDown(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y,
0);
break;
case WM_RBUTTONUP:
theInteractor->OnRButtonUp(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y);
break;
case WM_MOUSELEAVE: {
theInteractor->InvokeEvent(vtkCommand::LeaveEvent, NULL);
theInteractor->myMouseInWindow = 0;
}
break;
case WM_MOUSEMOVE:
theInteractor->OnMouseMove(theHWnd,
(UINT)theWParam,
MAKEPOINTS(theLParam).x,
MAKEPOINTS(theLParam).y);
break;
case WM_MOUSEWHEEL: {
POINT pt;
pt.x = MAKEPOINTS(theLParam).x;
pt.y = MAKEPOINTS(theLParam).y;
::ScreenToClient(theHWnd, &pt);
if (GET_WHEEL_DELTA_WPARAM(theWParam) > 0)
{
theInteractor->OnMouseWheelForward(theHWnd, (UINT)theWParam, pt.x, pt.y);
}
else
{
theInteractor->OnMouseWheelBackward(theHWnd, (UINT)theWParam, pt.x, pt.y);
}
}
break;
case WM_TIMER:
theInteractor->OnTimer(theHWnd, (UINT)theWParam);
break;
}
return DefWindowProcW(theHWnd, theMsg, theWParam, theLParam);
}
#else
//=================================================================================================
Display* IVtkDraw_Interactor::GetDisplayId() const
{
return myDisplayId;
}
//=================================================================================================
void IVtkDraw_Interactor::GetMousePosition(int* theX, int* theY)
{
Window aRoot, aChild;
int aRoot_x, aRoot_y;
unsigned int aKeys;
XQueryPointer(this->myDisplayId,
this->myWindowId,
&aRoot,
&aChild,
&aRoot_x,
&aRoot_y,
theX,
theY,
&aKeys);
}
//=================================================================================================
int IVtkDraw_Interactor::ViewerMainLoop(int theArgNum, const char** /*theArgs*/)
{
int aXp, aYp;
bool aPick = theArgNum > 0;
static XEvent anEvent;
XNextEvent(myDisplayId, &anEvent);
switch (anEvent.type)
{
case Expose: {
if (!this->Enabled)
{
return aPick;
}
XEvent aResult;
while (XCheckTypedWindowEvent(this->myDisplayId, this->myWindowId, Expose, &aResult))
{
// just getting the expose configure event
anEvent = aResult;
}
this->SetEventSize(anEvent.xexpose.width, anEvent.xexpose.height);
aXp = anEvent.xexpose.x;
aYp = this->Size[1] - anEvent.xexpose.y - 1;
this->SetEventPosition(aXp, aYp);
// only render if we are currently accepting events
if (this->Enabled)
{
this->InvokeEvent(vtkCommand::ExposeEvent, nullptr);
this->Render();
}
}
break;
case MapNotify: {
// only render if we are currently accepting events
if (this->Enabled && this->GetRenderWindow()->GetNeverRendered())
{
this->Render();
}
}
break;
case ConfigureNotify: {
XEvent aResult;
while (XCheckTypedWindowEvent(this->myDisplayId, this->myWindowId, ConfigureNotify, &aResult))
{
// just getting the last configure event
anEvent = aResult;
}
int aWidth = anEvent.xconfigure.width;
int aHeight = anEvent.xconfigure.height;
if (aWidth != this->Size[0] || aHeight != this->Size[1])
{
bool toResizeSmaller = aWidth <= this->Size[0] && aHeight <= this->Size[1];
this->UpdateSize(aWidth, aHeight);
aXp = anEvent.xbutton.x;
aYp = anEvent.xbutton.y;
SetEventPosition(aXp, this->Size[1] - aYp - 1);
// only render if we are currently accepting events
if (Enabled)
{
this->InvokeEvent(vtkCommand::ConfigureEvent, nullptr);
if (toResizeSmaller)
{
// Don't call Render when the window is resized to be larger:
//
// - if the window is resized to be larger, an Expose event will
// be triggered by the X server which will trigger a call to Render().
// - if the window is resized to be smaller, no Expose event will
// be triggered by the X server, as no new area become visible.
// only in this case, we need to explicitly call Render() in ConfigureNotify.
this->Render();
}
}
}
}
break;
case ButtonPress: {
if (!this->Enabled)
{
return aPick;
}
int aCtrl = anEvent.xbutton.state & ControlMask ? 1 : 0;
int aShift = anEvent.xbutton.state & ShiftMask ? 1 : 0;
int anAlt = anEvent.xbutton.state & Mod1Mask ? 1 : 0;
aXp = anEvent.xbutton.x;
aYp = anEvent.xbutton.y;
// check for double click
static int aMousePressTime = 0;
int aRepeat = 0;
// 400 ms threshold by default is probably good to start
int anEventTime = static_cast<int>(anEvent.xbutton.time);
if ((anEventTime - aMousePressTime) < 400)
{
aMousePressTime -= 2000; // no double click next time
aRepeat = 1;
}
else
{
aMousePressTime = anEventTime;
}
this->SetEventInformationFlipY(aXp, aYp, aCtrl, aShift, 0, aRepeat);
this->SetAltKey(anAlt);
switch (anEvent.xbutton.button)
{
case Button1:
this->OnSelection();
this->myIsLeftButtonPressed = true;
this->InvokeEvent(vtkCommand::LeftButtonPressEvent, nullptr);
break;
case Button2:
this->InvokeEvent(vtkCommand::MiddleButtonPressEvent, nullptr);
break;
case Button3:
this->InvokeEvent(vtkCommand::RightButtonPressEvent, nullptr);
break;
case Button4:
this->InvokeEvent(vtkCommand::MouseWheelForwardEvent, nullptr);
break;
case Button5:
this->InvokeEvent(vtkCommand::MouseWheelBackwardEvent, nullptr);
break;
}
this->Render();
}
break;
case ButtonRelease: {
if (!this->Enabled)
{
return aPick;
}
int aCtrl = anEvent.xbutton.state & ControlMask ? 1 : 0;
int aShift = anEvent.xbutton.state & ShiftMask ? 1 : 0;
int anAlt = anEvent.xbutton.state & Mod1Mask ? 1 : 0;
aXp = anEvent.xbutton.x;
aYp = anEvent.xbutton.y;
this->SetEventInformationFlipY(aXp, aYp, aCtrl, aShift);
this->SetAltKey(anAlt);
switch (anEvent.xbutton.button)
{
case Button1:
this->InvokeEvent(vtkCommand::LeftButtonReleaseEvent, nullptr);
this->myIsLeftButtonPressed = False;
break;
case Button2:
this->InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, nullptr);
break;
case Button3:
this->InvokeEvent(vtkCommand::RightButtonReleaseEvent, nullptr);
break;
}
this->Render();
}
break;
case EnterNotify: {
if (this->Enabled)
{
XEnterWindowEvent* anEnterEvent = reinterpret_cast<XEnterWindowEvent*>(&anEvent);
this->SetEventInformationFlipY(anEnterEvent->x,
anEnterEvent->y,
(anEnterEvent->state & ControlMask) != 0,
(anEnterEvent->state & ShiftMask) != 0);
this->SetAltKey(anEvent.xbutton.state & Mod1Mask ? 1 : 0);
this->InvokeEvent(vtkCommand::EnterEvent, nullptr);
}
this->Render();
}
break;
case LeaveNotify: {
if (this->Enabled)
{
XLeaveWindowEvent* aLeaveEvent = reinterpret_cast<XLeaveWindowEvent*>(&anEvent);
this->SetEventInformationFlipY(aLeaveEvent->x,
aLeaveEvent->y,
(aLeaveEvent->state & ControlMask) != 0,
(aLeaveEvent->state & ShiftMask) != 0);
this->SetAltKey(anEvent.xbutton.state & Mod1Mask ? 1 : 0);
this->InvokeEvent(vtkCommand::LeaveEvent, nullptr);
}
this->Render();
}
break;
case MotionNotify: {
if (!this->Enabled)
{
return aPick;
}
int aCtrl = anEvent.xbutton.state & ControlMask ? 1 : 0;
int aShift = anEvent.xbutton.state & ShiftMask ? 1 : 0;
int anAlt = anEvent.xbutton.state & Mod1Mask ? 1 : 0;
// Note that even though the (x,y) location of the pointer is event structure,
// we must call XQueryPointer for the hints (motion event compression) to
// work properly.
this->GetMousePosition(&aXp, &aYp);
this->SetEventInformationFlipY(aXp, aYp, aCtrl, aShift);
this->SetAltKey(anAlt);
if (!myIsLeftButtonPressed)
MoveTo(aXp, this->Size[1] - aYp - 1);
this->InvokeEvent(vtkCommand::MouseMoveEvent, nullptr);
}
break;
}
return aPick;
}
//=================================================================================================
void IVtkDraw_Interactor::ProcessEvents(ClientData theData, int)
{
IVtkDraw_Interactor* anInteractor = (IVtkDraw_Interactor*)theData;
// test for X Event
while (XPending(anInteractor->GetDisplayId()))
{
anInteractor->ViewerMainLoop(0, nullptr);
}
}
#endif
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.