/*========================================================================= Program: Visualization Toolkit Module: vtkVRMenuWidget.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkVRMenuWidget.h" #include "vtkCallbackCommand.h" #include "vtkEventData.h" #include "vtkObjectFactory.h" #include "vtkVRMenuRepresentation.h" #include "vtkWidgetCallbackMapper.h" #include "vtkWidgetEvent.h" vtkStandardNewMacro(vtkVRMenuWidget); class vtkVRMenuWidget::InternalElement { public: vtkCommand* Command; std::string Name; std::string Text; InternalElement() = default; }; //------------------------------------------------------------------------------ vtkVRMenuWidget::vtkVRMenuWidget() { // Set the initial state this->WidgetState = vtkVRMenuWidget::Start; this->EventCommand = vtkCallbackCommand::New(); this->EventCommand->SetClientData(this); this->EventCommand->SetCallback(vtkVRMenuWidget::EventCallback); { vtkNew ed; ed->SetDevice(vtkEventDataDevice::Any); ed->SetInput(vtkEventDataDeviceInput::Any); ed->SetAction(vtkEventDataAction::Release); this->CallbackMapper->SetCallbackMethod( vtkCommand::Menu3DEvent, ed, vtkWidgetEvent::Select, this, vtkVRMenuWidget::StartMenuAction); } { vtkNew ed; ed->SetDevice(vtkEventDataDevice::Any); ed->SetInput(vtkEventDataDeviceInput::Any); ed->SetAction(vtkEventDataAction::Release); this->CallbackMapper->SetCallbackMethod(vtkCommand::Select3DEvent, ed, vtkWidgetEvent::Select3D, this, vtkVRMenuWidget::SelectMenuAction); } { vtkNew ed; ed->SetDevice(vtkEventDataDevice::Any); ed->SetInput(vtkEventDataDeviceInput::Any); this->CallbackMapper->SetCallbackMethod( vtkCommand::Move3DEvent, ed, vtkWidgetEvent::Move3D, this, vtkVRMenuWidget::MoveAction); } } //------------------------------------------------------------------------------ vtkVRMenuWidget::~vtkVRMenuWidget() { this->EventCommand->Delete(); } //------------------------------------------------------------------------------ void vtkVRMenuWidget::PushFrontMenuItem(const char* name, const char* text, vtkCommand* cmd) { vtkVRMenuWidget::InternalElement* el = new vtkVRMenuWidget::InternalElement(); el->Text = text; el->Command = cmd; el->Name = name; this->Menus.push_front(el); static_cast(this->WidgetRep) ->PushFrontMenuItem(name, text, this->EventCommand); this->Modified(); } //------------------------------------------------------------------------------ void vtkVRMenuWidget::RenameMenuItem(const char* name, const char* text) { for (auto itr : this->Menus) { if (itr->Name == name) { itr->Text = text; } } static_cast(this->WidgetRep)->RenameMenuItem(name, text); } //------------------------------------------------------------------------------ void vtkVRMenuWidget::RemoveMenuItem(const char* name) { for (auto itr = this->Menus.begin(); itr != this->Menus.end(); ++itr) { if ((*itr)->Name == name) { delete *itr; this->Menus.erase(itr); break; } } static_cast(this->WidgetRep)->RemoveMenuItem(name); } //------------------------------------------------------------------------------ void vtkVRMenuWidget::RemoveAllMenuItems() { while (!this->Menus.empty()) { auto itr = this->Menus.begin(); delete *itr; this->Menus.erase(itr); } static_cast(this->WidgetRep)->RemoveAllMenuItems(); } //------------------------------------------------------------------------------ void vtkVRMenuWidget::EventCallback(vtkObject*, unsigned long, void* clientdata, void* calldata) { vtkVRMenuWidget* self = static_cast(clientdata); std::string name = static_cast(calldata); for (auto& menu : self->Menus) { if (menu->Name == name) { menu->Command->Execute( self, vtkWidgetEvent::Select3D, static_cast(const_cast(menu->Name.c_str()))); } } } //------------------------------------------------------------------------------ void vtkVRMenuWidget::ShowSubMenu(vtkVRMenuWidget* w) { w->SetInteractor(this->Interactor); w->Show(static_cast(this->CallData)); } //------------------------------------------------------------------------------ void vtkVRMenuWidget::Show(vtkEventData* ed) { this->On(); if (this->WidgetState == vtkVRMenuWidget::Start) { if (!this->Parent) { this->GrabFocus(this->EventCallbackCommand); } this->CallData = ed; this->WidgetRep->StartComplexInteraction(this->Interactor, this, vtkWidgetEvent::Select, ed); this->WidgetState = vtkVRMenuWidget::Active; } } //------------------------------------------------------------------------------ void vtkVRMenuWidget::StartMenuAction(vtkAbstractWidget* w) { vtkVRMenuWidget* self = reinterpret_cast(w); if (self->WidgetState == vtkVRMenuWidget::Active) { if (!self->Parent) { self->ReleaseFocus(); } self->Off(); self->WidgetState = vtkVRMenuWidget::Start; self->WidgetRep->EndComplexInteraction( self->Interactor, self, vtkWidgetEvent::Select, self->CallData); } } //------------------------------------------------------------------------------ void vtkVRMenuWidget::SelectMenuAction(vtkAbstractWidget* w) { vtkVRMenuWidget* self = reinterpret_cast(w); if (self->WidgetState != vtkVRMenuWidget::Active) { return; } if (!self->Parent) { self->ReleaseFocus(); } self->Off(); self->WidgetState = vtkVRMenuWidget::Start; self->WidgetRep->ComplexInteraction( self->Interactor, self, vtkWidgetEvent::Select3D, self->CallData); } //------------------------------------------------------------------------------ void vtkVRMenuWidget::MoveAction(vtkAbstractWidget* w) { vtkVRMenuWidget* self = reinterpret_cast(w); if (self->WidgetState != vtkVRMenuWidget::Active) { return; } self->WidgetRep->ComplexInteraction( self->Interactor, self, vtkWidgetEvent::Move3D, self->CallData); } //------------------------------------------------------------------------------ void vtkVRMenuWidget::SetRepresentation(vtkVRMenuRepresentation* rep) { this->Superclass::SetWidgetRepresentation(reinterpret_cast(rep)); } //------------------------------------------------------------------------------ void vtkVRMenuWidget::CreateDefaultRepresentation() { if (!this->WidgetRep) { this->WidgetRep = vtkVRMenuRepresentation::New(); } } //------------------------------------------------------------------------------ void vtkVRMenuWidget::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "WidgetState: " << this->WidgetState << "\n"; }