void RayMenuTool::buttonCallback(int,InputDevice::ButtonCallbackData* cbData) { if(cbData->newButtonState) // Button has just been pressed { /* Check if the GUI interactor refuses the event: */ GUIInteractor::updateRay(); if(!(factory->interactWithWidgets&&GUIInteractor::buttonDown(false))) { /* Try activating this tool: */ if(GUIInteractor::canActivate()&&activate()) { /*************************************************************** Pop up the tool's menu at the appropriate position and orientation: ***************************************************************/ if(isUseEyeRay()||interactionDevice->isRayDevice()) { /* Pop up the menu at the ray's intersection with the UI plane: */ popupPrimaryWidget(menu->getPopup(),calcRayPoint(GUIInteractor::getRay()),false); } else { /* Pop up the menu: */ popupPrimaryWidget(menu->getPopup(),GUIInteractor::getRay()(factory->initialMenuOffset),false); } /* Grab the pointer: */ getWidgetManager()->grabPointer(menu->getPopup()); /* Force the event on the GUI interactor: */ GUIInteractor::buttonDown(true); } } } else // Button has just been released { /* Check if the GUI interactor is active: */ if(GUIInteractor::isActive()) { /* Deliver the event: */ GUIInteractor::buttonUp(); /* Check if the tool's menu is popped up: */ if(MenuTool::isActive()) { /* Release the pointer: */ getWidgetManager()->releasePointer(menu->getPopup()); /* Pop down the menu: */ getWidgetManager()->popdownWidget(menu->getPopup()); /* Deactivate the tool: */ deactivate(); } } } }
void ewol::Widget::markToRedraw() { if (m_needRegenerateDisplay == true) { return; } m_needRegenerateDisplay = true; getWidgetManager().markDrawingIsNeeded(); }
MouseDialogNavigationTool::MouseDialogNavigationTool(const ToolFactory* factory,const ToolInputAssignment& inputAssignment) :NavigationTool(factory,inputAssignment), GUIInteractor(false,Scalar(0),getButtonDevice(0)), mouseAdapter(0), navigationDialogPopup(0), currentPos(Point::origin), navigationMode(ROTATING), spinning(false), showScreenCenter(false) { /* Find the mouse input device adapter controlling the input device: */ InputDevice* rootDevice=getInputGraphManager()->getRootDevice(getButtonDevice(0)); mouseAdapter=dynamic_cast<InputDeviceAdapterMouse*>(getInputDeviceManager()->findInputDeviceAdapter(rootDevice)); /* Create the tool's GUI: */ navigationDialogPopup=new GLMotif::PopupWindow("NavigationDialogPopup",getWidgetManager(),"Mouse Navigation Dialog"); GLMotif::RowColumn* navigationDialog=new GLMotif::RowColumn("NavigationDialog",navigationDialogPopup,false); GLMotif::RadioBox* navigationModes=new GLMotif::RadioBox("NavigationModes",navigationDialog,false); navigationModes->setOrientation(GLMotif::RowColumn::VERTICAL); navigationModes->setPacking(GLMotif::RowColumn::PACK_GRID); navigationModes->setSelectionMode(GLMotif::RadioBox::ALWAYS_ONE); navigationModes->addToggle("Rotate"); navigationModes->addToggle("Pan"); navigationModes->addToggle("Dolly"); navigationModes->addToggle("Scale"); switch(navigationMode) { case ROTATING: navigationModes->setSelectedToggle(0); break; case PANNING: navigationModes->setSelectedToggle(1); break; case DOLLYING: navigationModes->setSelectedToggle(2); break; case SCALING: navigationModes->setSelectedToggle(3); break; } navigationModes->getValueChangedCallbacks().add(this,&MouseDialogNavigationTool::navigationModesValueChangedCallback); navigationModes->manageChild(); GLMotif::ToggleButton* showScreenCenterToggle=new GLMotif::ToggleButton("ShowScreenCenterToggle",navigationDialog,"Show Screen Center"); showScreenCenterToggle->setToggle(showScreenCenter); showScreenCenterToggle->getValueChangedCallbacks().add(this,&MouseDialogNavigationTool::showScreenCenterToggleValueChangedCallback); navigationDialog->manageChild(); /* Pop up the navigation dialog: */ popupPrimaryWidget(navigationDialogPopup); }
void SketchingTool::loadCurvesCallback(Misc::CallbackData* cbData) { /* Create a file selection dialog to select a curve file: */ GLMotif::FileSelectionDialog* loadCurvesDialog=new GLMotif::FileSelectionDialog(getWidgetManager(),"Load Curves...",0,".curves",openPipe()); loadCurvesDialog->getOKCallbacks().add(this,&SketchingTool::loadCurvesOKCallback); loadCurvesDialog->getCancelCallbacks().add(loadCurvesDialog,&GLMotif::FileSelectionDialog::defaultCloseCallback); /* Show the file selection dialog: */ popupPrimaryWidget(loadCurvesDialog); }
PanelMenuTool::~PanelMenuTool(void) { if(isActive()) { /* Pop down the menu: */ getWidgetManager()->popdownWidget(menu->getPopup()); /* Deactivate the tool again: */ deactivate(); } }
void RayScreenMenuTool::frame(void) { /* Update the selection ray: */ selectionRay=calcSelectionRay(); if(factory->interactWithWidgets) insideWidget=getWidgetManager()->findPrimaryWidget(selectionRay)!=0; if(widgetActive) { /* Deliver the event: */ GLMotif::Event event(true); event.setWorldLocation(selectionRay); getWidgetManager()->pointerMotion(event); if(dragging) { /* Find the closest intersection with any screen: */ std::pair<VRScreen*,Scalar> si=findScreen(selectionRay); if(si.first!=0) { /* Update the dragged widget's transformation: */ NavTrackerState current=NavTrackerState::translateFromOriginTo(selectionRay(si.second)); current*=preScale; getWidgetManager()->setPrimaryWidgetTransformation(draggedWidget,GLMotif::WidgetManager::Transformation(current)); } } } else if(isActive()) { /* Update the selection ray: */ selectionRay=calcSelectionRay(); /* Deliver the event: */ GLMotif::Event event(true); event.setWorldLocation(selectionRay); getWidgetManager()->pointerMotion(event); } }
bool ewol::widget::Container::loadXML(exml::Element* _node) { if (nullptr == _node) { return false; } // parse generic properties : ewol::Widget::loadXML(_node); // remove previous element : subWidgetRemove(); // parse all the elements : for(size_t iii=0; iii< _node->size(); iii++) { exml::Element* pNode = _node->getElement(iii); if (pNode == nullptr) { // trash here all that is not element continue; } std::string widgetName = pNode->getValue(); if (getWidgetManager().exist(widgetName) == false) { EWOL_ERROR("(l "<<pNode->getPos()<<") Unknown basic node=\"" << widgetName << "\" not in : [" << getWidgetManager().list() << "]" ); continue; } if (nullptr != getSubWidget()) { EWOL_ERROR("(l "<<pNode->getPos()<<") " << __class__ << " Can only have one subWidget ??? node=\"" << widgetName << "\"" ); continue; } EWOL_DEBUG("try to create subwidget : '" << widgetName << "'"); std::shared_ptr<ewol::Widget> tmpWidget = getWidgetManager().create(widgetName); if (tmpWidget == nullptr) { EWOL_ERROR ("(l "<<pNode->getPos()<<") Can not create the widget : \"" << widgetName << "\""); continue; } // add widget : setSubWidget(tmpWidget); if (false == tmpWidget->loadXML(pNode)) { EWOL_ERROR ("(l "<<pNode->getPos()<<") can not load widget properties : \"" << widgetName << "\""); return false; } } return true; }
void PanelMenuTool::frame(void) { if(isActive()) { /* Calculate the menu transformation: */ GLMotif::WidgetManager::Transformation menuTransformation=getDeviceTransformation(0); GLMotif::Vector topLeft=menu->getPopup()->getExterior().getCorner(2); menuTransformation*=GLMotif::WidgetManager::Transformation::translate(-Vector(topLeft.getXyzw())); /* Set the menu's position: */ getWidgetManager()->setPrimaryWidgetTransformation(menu->getPopup(),menuTransformation); } }
void ViewpointFileNavigationTool::createGui(void) { const GLMotif::StyleSheet& ss=*getWidgetManager()->getStyleSheet(); /* Create the playback control dialog window: */ controlDialogPopup=new GLMotif::PopupWindow("ControlDialogPopup",getWidgetManager(),"Playback Control"); controlDialogPopup->setResizableFlags(true,false); GLMotif::RowColumn* controlDialog=new GLMotif::RowColumn("ControlDialog",controlDialogPopup,false); controlDialog->setOrientation(GLMotif::RowColumn::VERTICAL); controlDialog->setPacking(GLMotif::RowColumn::PACK_TIGHT); controlDialog->setNumMinorWidgets(2); new GLMotif::Label("PositionLabel",controlDialog,"Position"); positionSlider=new GLMotif::TextFieldSlider("PositionSlider",controlDialog,8,ss.fontHeight*10.0f); positionSlider->getTextField()->setFloatFormat(GLMotif::TextField::FIXED); positionSlider->getTextField()->setFieldWidth(7); positionSlider->getTextField()->setPrecision(1); positionSlider->setValueRange(splines.front().t[0],splines.back().t[1],1.0); positionSlider->setValue(parameter); positionSlider->getValueChangedCallbacks().add(this,&ViewpointFileNavigationTool::positionSliderCallback); new GLMotif::Label("SpeedLabel",controlDialog,"Speed"); GLMotif::TextFieldSlider* speedSlider=new GLMotif::TextFieldSlider("SpeedSlider",controlDialog,8,ss.fontHeight*10.0f); speedSlider->getTextField()->setFloatFormat(GLMotif::TextField::FIXED); speedSlider->getTextField()->setFieldWidth(7); speedSlider->getTextField()->setPrecision(2); speedSlider->setValueRange(-2.0,2.0,0.01); speedSlider->getSlider()->addNotch(-1.0f); speedSlider->getSlider()->addNotch(1.0f); speedSlider->setValue(speed); speedSlider->getValueChangedCallbacks().add(this,&ViewpointFileNavigationTool::speedSliderCallback); controlDialog->manageChild(); popupPrimaryWidget(controlDialogPopup); }
void PanelMenuTool::setMenu(MutexMenu* newMenu) { /* Call the base class method first: */ MenuTool::setMenu(newMenu); /* Try activating this tool (it will grab the main menu until it is destroyed): */ if(activate()) { /* Calculate the menu transformation: */ GLMotif::WidgetManager::Transformation menuTransformation=getDeviceTransformation(0); GLMotif::Vector topLeft=menu->getPopup()->getExterior().getCorner(2); menuTransformation*=GLMotif::WidgetManager::Transformation::translate(-Vector(topLeft.getXyzw())); /* Pop up the menu: */ getWidgetManager()->popupPrimaryWidget(menu->getPopup(),menuTransformation); } }
void MouseNavigationTool::buttonCallback(int,int buttonIndex,InputDevice::ButtonCallbackData* cbData) { /* Process based on which button was pressed: */ switch(buttonIndex) { case 0: if(cbData->newButtonState) // Button has just been pressed { /* Act depending on this tool's current state: */ switch(navigationMode) { case IDLE: case SPINNING: if(factory->interactWithWidgets) { /* Check if the mouse pointer is over a GLMotif widget: */ GLMotif::Event event(false); event.setWorldLocation(calcSelectionRay()); if(getWidgetManager()->pointerButtonDown(event)) { if(navigationMode==SPINNING) { /* Deactivate this tool: */ deactivate(); } /* Go to widget interaction mode: */ navigationMode=WIDGETING; /* Drag the entire root widget if the event's target widget is a title bar: */ if(dynamic_cast<GLMotif::TitleBar*>(event.getTargetWidget())!=0) { /* Start dragging: */ draggedWidget=event.getTargetWidget(); /* Calculate the dragging transformation: */ NavTrackerState initialTracker=NavTrackerState::translateFromOriginTo(calcScreenPos()); preScale=Geometry::invert(initialTracker); GLMotif::WidgetManager::Transformation initialWidget=getWidgetManager()->calcWidgetTransformation(draggedWidget); preScale*=NavTrackerState(initialWidget); } else draggedWidget=0; } else { /* Try activating this tool: */ if(navigationMode==SPINNING||activate()) startRotating(); } } else { /* Try activating this tool: */ if(navigationMode==SPINNING||activate()) startRotating(); } break; case PANNING: if(dolly) startDollying(); else startScaling(); break; default: /* This shouldn't happen; just ignore the event */ break; } } else // Button has just been released { /* Act depending on this tool's current state: */ switch(navigationMode) { case WIDGETING: { /* Deliver the event: */ GLMotif::Event event(true); event.setWorldLocation(calcSelectionRay()); getWidgetManager()->pointerButtonUp(event); /* Deactivate this tool: */ navigationMode=IDLE; draggedWidget=0; break; } case ROTATING: { /* Check if the input device is still moving: */ Point currentPos=calcScreenPos(); Vector delta=currentPos-lastRotationPos; if(Geometry::mag(delta)>factory->spinThreshold) { /* Calculate spinning angular velocity: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; Vector axis=Geometry::cross(offset,delta); Scalar angularVelocity=Geometry::mag(delta)/(factory->rotateFactor*getCurrentFrameTime()); spinAngularVelocity=axis*(Scalar(0.5)*angularVelocity/axis.mag()); /* Go to spinning mode: */ navigationMode=SPINNING; } else { /* Deactivate this tool: */ deactivate(); /* Go to idle mode: */ navigationMode=IDLE; } break; } case DOLLYING: case SCALING: startPanning(); break; default: /* This shouldn't happen; just ignore the event */ break; } } break; case 1: if(cbData->newButtonState) // Button has just been pressed { /* Act depending on this tool's current state: */ switch(navigationMode) { case IDLE: case SPINNING: /* Try activating this tool: */ if(navigationMode==SPINNING||activate()) startPanning(); break; case ROTATING: if(dolly) startDollying(); else startScaling(); break; default: /* This shouldn't happen; just ignore the event */ break; } } else // Button has just been released { /* Act depending on this tool's current state: */ switch(navigationMode) { case PANNING: /* Deactivate this tool: */ deactivate(); /* Go to idle mode: */ navigationMode=IDLE; break; case DOLLYING: case SCALING: startRotating(); break; default: /* This shouldn't happen; just ignore the event */ break; } } break; case 2: /* Set the dolly flag: */ dolly=cbData->newButtonState; if(factory->invertDolly) dolly=!dolly; if(dolly) // Dollying has just been enabled { /* Act depending on this tool's current state: */ switch(navigationMode) { case SCALING: startDollying(); break; default: /* Nothing to do */ break; } } else { /* Act depending on this tool's current state: */ switch(navigationMode) { case DOLLYING: startScaling(); break; default: /* Nothing to do */ break; } } break; } }
void RayScreenMenuTool::buttonCallback(int,int,InputDevice::ButtonCallbackData* cbData) { if(cbData->newButtonState) // Activation button has just been pressed { /* Check if the tool is interacting with a widget: */ if(factory->interactWithWidgets) { /* If the widget manager accepts the event, preempt any cascaded tools until the button is released: */ Ray ray=calcSelectionRay(); GLMotif::Event event(false); event.setWorldLocation(ray); if(getWidgetManager()->pointerButtonDown(event)) { /* Activate the widget tool: */ widgetActive=true; /* Drag the entire root widget if the event's target widget is a title bar: */ if(dynamic_cast<GLMotif::TitleBar*>(event.getTargetWidget())!=0) { /* Find the closest intersection with any screen: */ std::pair<VRScreen*,Scalar> si=findScreen(ray); if(si.first!=0) { /* Start dragging: */ dragging=true; draggedWidget=event.getTargetWidget(); /* Calculate the dragging transformation: */ NavTrackerState initialTracker=NavTrackerState::translateFromOriginTo(ray(si.second)); preScale=Geometry::invert(initialTracker); GLMotif::WidgetManager::Transformation initialWidget=getWidgetManager()->calcWidgetTransformation(draggedWidget); preScale*=NavTrackerState(initialWidget); } } /* Cancel processing of this callback to preempt cascaded tools: */ cbData->callbackList->requestInterrupt(); } } /* Try activating this tool: */ if(!widgetActive&&activate()) { /* Calculate the menu selection ray: */ Ray ray=calcSelectionRay(); /* Find the closest intersection with any screen: */ std::pair<VRScreen*,Scalar> si=findScreen(ray); if(si.first!=0) { typedef GLMotif::WidgetManager::Transformation WTransform; typedef WTransform::Point WPoint; typedef WTransform::Vector WVector; /* Calculate the menu transformation: */ WPoint globalHotSpot=ray(si.second); /* Try to align the menu with the viewing direction: */ ONTransform screenT=si.first->getScreenTransformation(); WTransform menuTransformation=WTransform::translate(globalHotSpot-screenT.getOrigin()); menuTransformation*=screenT; GLMotif::Vector menuHotSpot=menu->getPopup()->calcHotSpot(); menuTransformation*=WTransform::translate(-WVector(menuHotSpot.getXyzw())); /* Pop up the menu: */ getWidgetManager()->popupPrimaryWidget(menu->getPopup(),menuTransformation); /* Deliver the event: */ GLMotif::Event event(false); event.setWorldLocation(ray); getWidgetManager()->pointerButtonDown(event); } else deactivate(); } } else // Activation button has just been released { if(widgetActive) { /* Deliver the event: */ GLMotif::Event event(true); event.setWorldLocation(calcSelectionRay()); getWidgetManager()->pointerButtonUp(event); /* Deactivate this tool: */ dragging=false; widgetActive=false; /* Cancel processing of this callback to preempt cascaded tools: */ cbData->callbackList->requestInterrupt(); } else if(isActive()) { /* Deliver the event: */ GLMotif::Event event(true); event.setWorldLocation(calcSelectionRay()); getWidgetManager()->pointerButtonUp(event); /* Pop down the menu: */ getWidgetManager()->popdownWidget(menu->getPopup()); /* Deactivate the tool: */ deactivate(); } } }
void ewol::Widget::keepFocus() { getWidgetManager().focusKeep(std::dynamic_pointer_cast<ewol::Widget>(shared_from_this())); }
void InputDeviceAdapterMouse::updateInputDevices(void) { if(window!=0) { /* Set mouse device's transformation and device ray: */ Point lastMousePos=inputDevices[0]->getPosition(); window->updateMouseDevice(mousePos,inputDevices[0]); /* Calculate the mouse device's linear velocity: */ inputDevices[0]->setLinearVelocity((inputDevices[0]->getPosition()-lastMousePos)/Vrui::getFrameTime()); if(mouseLocked) { /* Move the mouse cursor back to the window center: */ int windowCenter[2]; window->getWindowCenterPos(windowCenter); if(mousePos[0]!=windowCenter[0]||mousePos[1]!=windowCenter[1]) { for(int i=0; i<2; ++i) mousePos[i]=windowCenter[i]; window->setCursorPos(mousePos[0],mousePos[1]); /* Reset the mouse device's ray and transformation to the locked values: */ inputDevices[0]->setDeviceRay(lockedRayDirection,lockedRayStart); inputDevices[0]->setTransformation(lockedTransformation); } } /* Set mouse device button states: */ for(int i=0; i<numButtonStates; ++i) inputDevices[0]->setButtonState(i,buttonStates[i]); /* Set mouse device valuator states: */ int numValuators=1<<numModifierKeys; for(int i=0; i<numValuators; ++i) { /* Convert the mouse wheel tick count into a valuator value (ugh): */ double mouseWheelValue=double(numMouseWheelTicks[i])/3.0; if(mouseWheelValue<-1.0) mouseWheelValue=-1.0; else if(mouseWheelValue>1.0) mouseWheelValue=1.0; inputDevices[0]->setValuator(i,mouseWheelValue); /* If there were mouse ticks, request another Vrui frame in a short while because there will be no "no mouse ticks" message: */ if(numMouseWheelTicks[i]!=0) scheduleUpdate(getApplicationTime()+0.1); numMouseWheelTicks[i]=0; } #if 0 inputDevices[0]->setValuator(numValuators+0,Scalar(2)*mousePos[0]/window->getVRScreen()->getWidth()-Scalar(1)); inputDevices[0]->setValuator(numValuators+1,Scalar(2)*mousePos[1]/window->getVRScreen()->getHeight()-Scalar(1)); inputDevices[0]->setValuator(numValuators+2,0.0); inputDevices[0]->setValuator(numValuators+3,0.0); #endif } if(!textEvents.empty()||!textControlEvents.empty()) { /* Process all accumulated text and text control events: */ std::vector<std::pair<int,GLMotif::TextEvent> >::iterator teIt=textEvents.begin(); int teOrd=teIt!=textEvents.end()?teIt->first:nextEventOrdinal; std::vector<std::pair<int,GLMotif::TextControlEvent> >::iterator tceIt=textControlEvents.begin(); int tceOrd=tceIt!=textControlEvents.end()?tceIt->first:nextEventOrdinal; while(teIt!=textEvents.end()||tceIt!=textControlEvents.end()) { /* Process the next event from either list: */ if(teOrd<tceOrd) { getWidgetManager()->text(teIt->second); ++teIt; teOrd=teIt!=textEvents.end()?teIt->first:nextEventOrdinal; } else { getWidgetManager()->textControl(tceIt->second); ++tceIt; tceOrd=tceIt!=textControlEvents.end()?tceIt->first:nextEventOrdinal; } } /* Clear the event lists: */ nextEventOrdinal=0; textEvents.clear(); textControlEvents.clear(); } }
SketchingTool::SketchingTool(const ToolFactory* factory,const ToolInputAssignment& inputAssignment) :UtilityTool(factory,inputAssignment), controlDialogPopup(0),lineWidthValue(0),colorBox(0), newLineWidth(3.0f),newColor(255,0,0), active(false) { /* Get the style sheet: */ const GLMotif::StyleSheet* ss=getWidgetManager()->getStyleSheet(); /* Build the tool control dialog: */ controlDialogPopup=new GLMotif::PopupWindow("SketchingToolControlDialog",getWidgetManager(),"Curve Editor Settings"); controlDialogPopup->setResizableFlags(false,false); GLMotif::RowColumn* controlDialog=new GLMotif::RowColumn("ControlDialog",controlDialogPopup,false); controlDialog->setNumMinorWidgets(1); GLMotif::RowColumn* settingsBox=new GLMotif::RowColumn("SettingsBox",controlDialog,false); settingsBox->setNumMinorWidgets(2); /* Create a slider to set the line width: */ new GLMotif::Label("LineWidthLabel",settingsBox,"Line Width"); GLMotif::RowColumn* lineWidthBox=new GLMotif::RowColumn("LineWidthBox",settingsBox,false); lineWidthBox->setOrientation(GLMotif::RowColumn::HORIZONTAL); lineWidthValue=new GLMotif::TextField("LineWidthValue",lineWidthBox,4); lineWidthValue->setFloatFormat(GLMotif::TextField::FIXED); lineWidthValue->setPrecision(1); lineWidthValue->setValue(newLineWidth); GLMotif::Slider* lineWidthSlider=new GLMotif::Slider("LineWidthSlider",lineWidthBox,GLMotif::Slider::HORIZONTAL,ss->fontHeight*10.0f); lineWidthSlider->setValueRange(0.5,11.0,0.5); lineWidthSlider->setValue(newLineWidth); lineWidthSlider->getValueChangedCallbacks().add(this,&SketchingTool::lineWidthSliderCallback); lineWidthBox->manageChild(); /* Create a radio box to set the line color: */ new GLMotif::Label("ColorLabel",settingsBox,"Color"); colorBox=new GLMotif::RowColumn("ColorBox",settingsBox,false); colorBox->setOrientation(GLMotif::RowColumn::HORIZONTAL); colorBox->setPacking(GLMotif::RowColumn::PACK_GRID); colorBox->setAlignment(GLMotif::Alignment::LEFT); /* Add the color buttons: */ for(int i=0;i<8;++i) { char colorButtonName[16]; snprintf(colorButtonName,sizeof(colorButtonName),"ColorButton%d",i); GLMotif::NewButton* colorButton=new GLMotif::NewButton(colorButtonName,colorBox,GLMotif::Vector(ss->fontHeight,ss->fontHeight,0.0f)); colorButton->setBackgroundColor(GLMotif::Color(curveColors[i])); colorButton->getSelectCallbacks().add(this,&SketchingTool::colorButtonSelectCallback); } colorBox->manageChild(); settingsBox->manageChild(); GLMotif::RowColumn* buttonBox=new GLMotif::RowColumn("ButtonBox",controlDialog,false); buttonBox->setOrientation(GLMotif::RowColumn::HORIZONTAL); buttonBox->setPacking(GLMotif::RowColumn::PACK_TIGHT); buttonBox->setAlignment(GLMotif::Alignment::RIGHT); GLMotif::NewButton* saveCurvesButton=new GLMotif::NewButton("SaveCurvesButton",buttonBox,"Save Curves"); saveCurvesButton->getSelectCallbacks().add(this,&SketchingTool::saveCurvesCallback); GLMotif::NewButton* loadCurvesButton=new GLMotif::NewButton("LoadCurvesButton",buttonBox,"Load Curves"); loadCurvesButton->getSelectCallbacks().add(this,&SketchingTool::loadCurvesCallback); GLMotif::NewButton* deleteAllCurvesButton=new GLMotif::NewButton("DeleteAllCurvesButton",buttonBox,"Delete All Curves"); deleteAllCurvesButton->getSelectCallbacks().add(this,&SketchingTool::deleteAllCurvesCallback); buttonBox->manageChild(); controlDialog->manageChild(); /* Pop up the control dialog: */ popupPrimaryWidget(controlDialogPopup); }
void MouseNavigationTool::frame(void) { /* Update the current mouse position: */ currentPos=calcScreenPos(); /* Act depending on this tool's current state: */ switch(navigationMode) { case IDLE: /* Do nothing */ break; case WIDGETING: { /* Deliver the event: */ GLMotif::Event event(true); event.setWorldLocation(calcSelectionRay()); getWidgetManager()->pointerMotion(event); if(draggedWidget!=0) { /* Update the dragged widget's transformation: */ NavTrackerState current=NavTrackerState::translateFromOriginTo(calcScreenPos()); current*=preScale; getWidgetManager()->setPrimaryWidgetTransformation(draggedWidget,GLMotif::WidgetManager::Transformation(current)); } break; } case ROTATING: { /* Calculate the rotation position: */ Vector offset=(lastRotationPos-screenCenter)+rotateOffset; /* Calculate mouse displacement vector: */ Point rotationPos=currentPos; Vector delta=rotationPos-lastRotationPos; lastRotationPos=rotationPos; /* Calculate incremental rotation: */ Vector axis=Geometry::cross(offset,delta); Scalar angle=Geometry::mag(delta)/factory->rotateFactor; if(angle!=Scalar(0)) rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateAxis(axis,angle))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); break; } case SPINNING: { /* Calculate incremental rotation: */ rotation.leftMultiply(NavTrackerState::rotate(NavTrackerState::Rotation::rotateScaledAxis(spinAngularVelocity*getCurrentFrameTime()))); NavTrackerState t=preScale; t*=rotation; t*=postScale; setNavigationTransformation(t); break; } case PANNING: { /* Update the navigation transformation: */ NavTrackerState t=NavTrackerState::translate(currentPos-motionStart); t*=preScale; setNavigationTransformation(t); break; } case DOLLYING: { /* Calculate the current dollying direction: */ Vector dollyingDirection; if(mouseAdapter!=0) dollyingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenDollyingDirection); else dollyingDirection=getMainScreen()->getScreenTransformation().transform(factory->screenDollyingDirection); /* Update the navigation transformation: */ Scalar dollyDist=((currentPos-motionStart)*dollyingDirection)/factory->dollyFactor; NavTrackerState t=NavTrackerState::translate(dollyDirection*dollyDist); t*=preScale; setNavigationTransformation(t); break; } case SCALING: { /* Calculate the current scaling direction: */ Vector scalingDirection; if(mouseAdapter!=0) scalingDirection=mouseAdapter->getWindow()->getVRScreen()->getScreenTransformation().transform(factory->screenScalingDirection); else scalingDirection=getMainScreen()->getScreenTransformation().transform(factory->screenScalingDirection); /* Update the navigation transformation: */ Scalar scale=((currentPos-motionStart)*scalingDirection)/factory->scaleFactor; NavTrackerState t=preScale; t*=NavTrackerState::scale(Math::exp(scale)); t*=postScale; setNavigationTransformation(t); break; } case DOLLYING_WHEEL: { /* Update the navigation transformation: */ Scalar scale=currentValue; currentWheelScale+=factory->wheelDollyFactor*scale; NavTrackerState t=NavTrackerState::translate(dollyDirection*currentWheelScale); t*=preScale; setNavigationTransformation(t); break; } case SCALING_WHEEL: { /* Update the navigation transformation: */ Scalar scale=currentValue; currentWheelScale*=Math::pow(factory->wheelScaleFactor,scale); NavTrackerState t=preScale; t*=NavTrackerState::scale(currentWheelScale); t*=postScale; setNavigationTransformation(t); break; } } }
void ViewerConfiguration::buildViewerConfigurationControls(void) { /* Build the graphical user interface: */ const GLMotif::StyleSheet& ss=*getUiStyleSheet(); dialogWindow=new GLMotif::PopupWindow("ViewerConfigurationDialog",getWidgetManager(),"Viewer Configuration"); dialogWindow->setHideButton(true); dialogWindow->setResizableFlags(true,false); GLMotif::RowColumn* viewerConfiguration=new GLMotif::RowColumn("ViewerConfiguration",dialogWindow,false); viewerConfiguration->setOrientation(GLMotif::RowColumn::VERTICAL); viewerConfiguration->setPacking(GLMotif::RowColumn::PACK_TIGHT); viewerConfiguration->setNumMinorWidgets(2); /* Create a drop-down menu to select a viewer: */ new GLMotif::Label("ViewerLabel",viewerConfiguration,"Viewer"); viewerMenu=new GLMotif::DropdownBox("ViewerMenu",viewerConfiguration); int mainViewerIndex=0; for(int viewerIndex=0;viewerIndex<getNumViewers();++viewerIndex) { Viewer* viewer=getViewer(viewerIndex); viewerMenu->addItem(viewer->getName()); if(viewer==getMainViewer()) mainViewerIndex=viewerIndex; } viewerMenu->setSelectedItem(mainViewerIndex); viewerMenu->getValueChangedCallbacks().add(this,&ViewerConfiguration::viewerMenuCallback); /* Calculate an appropriate slider range and granularity: */ Scalar sliderRange=Scalar(18)*factory->configUnit.getInchFactor(); // Slider range is at least 18" Scalar sliderRangeFactor=Math::pow(Scalar(10),Math::floor(Math::log10(sliderRange))); sliderRange=Math::ceil(sliderRange/sliderRangeFactor)*sliderRangeFactor; Scalar sliderStep=Scalar(0.01)*factory->configUnit.getInchFactor(); // Slider granularity is at most 0.01" int sliderStepDigits=int(Math::floor(Math::log10(sliderStep))); Scalar sliderStepFactor=Math::pow(Scalar(10),Scalar(sliderStepDigits)); sliderStep=Math::floor(sliderStep/sliderStepFactor)*sliderStepFactor; sliderStepDigits=sliderStepDigits<0?-sliderStepDigits:0; /* Create three sliders to set the mono eye position: */ new GLMotif::Label("MonoEyePosLabel",viewerConfiguration,"Mono Eye"); GLMotif::RowColumn* monoEyePosBox=new GLMotif::RowColumn("MonoEyePosBox",viewerConfiguration,false); monoEyePosBox->setPacking(GLMotif::RowColumn::PACK_GRID); for(int i=0;i<3;++i) { char epsName[14]="EyePosSlider "; epsName[12]=char(i+'0'); eyePosSliders[0][i]=new GLMotif::TextFieldSlider(epsName,monoEyePosBox,7,ss.fontHeight*10.0f); eyePosSliders[0][i]->getTextField()->setFieldWidth(6); eyePosSliders[0][i]->getTextField()->setPrecision(sliderStepDigits); eyePosSliders[0][i]->getTextField()->setFloatFormat(GLMotif::TextField::FIXED); eyePosSliders[0][i]->setSliderMapping(GLMotif::TextFieldSlider::LINEAR); eyePosSliders[0][i]->setValueType(GLMotif::TextFieldSlider::FLOAT); eyePosSliders[0][i]->setValueRange(-sliderRange,sliderRange,sliderStep); eyePosSliders[0][i]->getValueChangedCallbacks().add(this,&ViewerConfiguration::eyePosSliderCallback,i); } monoEyePosBox->manageChild(); /* Create a slider to set the eye separation distance: */ new GLMotif::Label("EyeDistLabel",viewerConfiguration,"Eye Distance"); eyeDistanceSlider=new GLMotif::TextFieldSlider("EyeDistanceSlider",viewerConfiguration,7,ss.fontHeight*10.0f); eyeDistanceSlider->getTextField()->setFieldWidth(6); eyeDistanceSlider->getTextField()->setPrecision(sliderStepDigits); eyeDistanceSlider->getTextField()->setFloatFormat(GLMotif::TextField::FIXED); eyeDistanceSlider->setSliderMapping(GLMotif::TextFieldSlider::LINEAR); eyeDistanceSlider->setValueType(GLMotif::TextFieldSlider::FLOAT); eyeDistanceSlider->setValueRange(sliderStep*Scalar(10),sliderRange,sliderStep); eyeDistanceSlider->getValueChangedCallbacks().add(this,&ViewerConfiguration::eyeDistanceSliderCallback); /* Create two triples of sliders to set the left and right eye positions: */ for(int eyeIndex=1;eyeIndex<3;++eyeIndex) { /* Create a separator: */ new GLMotif::Blind(eyeIndex==1?"Blind1":"Blind2",viewerConfiguration); new GLMotif::Separator(eyeIndex==1?"Separator1":"Separator2",viewerConfiguration,GLMotif::Separator::HORIZONTAL,ss.fontHeight,GLMotif::Separator::LOWERED); /* Create three sliders to set the left or right eye position: */ new GLMotif::Label(eyeIndex==1?"LeftEyePosLabel":"RightEyePosLabel",viewerConfiguration,eyeIndex==1?"Left Eye":"Right Eye"); GLMotif::RowColumn* eyePosBox=new GLMotif::RowColumn(eyeIndex==1?"LeftEyePosBox":"RightEyePosBox",viewerConfiguration,false); eyePosBox->setPacking(GLMotif::RowColumn::PACK_GRID); for(int i=0;i<3;++i) { char epsName[14]="EyePosSlider "; epsName[12]=char(eyeIndex*3+i+'0'); eyePosSliders[eyeIndex][i]=new GLMotif::TextFieldSlider(epsName,eyePosBox,7,ss.fontHeight*10.0f); eyePosSliders[eyeIndex][i]->getTextField()->setFieldWidth(6); eyePosSliders[eyeIndex][i]->getTextField()->setPrecision(sliderStepDigits); eyePosSliders[eyeIndex][i]->getTextField()->setFloatFormat(GLMotif::TextField::FIXED); eyePosSliders[eyeIndex][i]->setSliderMapping(GLMotif::TextFieldSlider::LINEAR); eyePosSliders[eyeIndex][i]->setValueType(GLMotif::TextFieldSlider::FLOAT); eyePosSliders[eyeIndex][i]->setValueRange(-sliderRange,sliderRange,sliderStep); eyePosSliders[eyeIndex][i]->getValueChangedCallbacks().add(this,&ViewerConfiguration::eyePosSliderCallback,eyeIndex*3+i); } eyePosBox->manageChild(); } viewerConfiguration->manageChild(); /* Initialize vislet state and GUI: */ setViewer(getViewer(mainViewerIndex)); }
void MessageLogger::showMessageDialog(int messageLevel,const char* messageString) { /* Assemble the dialog title: */ std::string title=messageLevel<Warning?"Note":messageLevel<Error?"Warning":"Error"; /* Check if the messageString starts with a source identifier: */ const char* colonPtr=0; for(const char* mPtr=messageString;*mPtr!='\0'&&!isspace(*mPtr);++mPtr) if(*mPtr==':') colonPtr=mPtr; if(colonPtr!=0&&colonPtr[1]!='\0'&&isspace(colonPtr[1])) { /* Append the messageString source to the title: */ title.append(" from "); title.append(messageString,colonPtr); /* Cut the source from the messageString: */ messageString=colonPtr+1; } /* Create a popup window: */ GLMotif::PopupWindow* messageDialog=new GLMotif::PopupWindow("VruiMessageLoggerMessage",getWidgetManager(),title.c_str()); messageDialog->setResizableFlags(false,false); messageDialog->setHideButton(false); GLMotif::RowColumn* message=new GLMotif::RowColumn("Message",messageDialog,false); message->setOrientation(GLMotif::RowColumn::VERTICAL); message->setPacking(GLMotif::RowColumn::PACK_TIGHT); /* Skip initial whitespace in the message message: */ const char* linePtr=messageString; while(*linePtr!='\0'&&isspace(*linePtr)) ++linePtr; /* Break the message message into multiple lines: */ while(*linePtr!='\0') { /* Find potential line break points: */ const char* breakPtr=0; const char* cPtr=linePtr; do { /* Find the end of the current word: */ while(!isspace(*cPtr)&&*cPtr!='-'&&*cPtr!='/'&&*cPtr!='\0') ++cPtr; /* Skip past dashes and slashes: */ while(*cPtr=='-'||*cPtr=='/') ++cPtr; /* If the line is already too long, and there is a previous break point, break there: */ if(cPtr-linePtr>=40&&breakPtr!=0) break; /* Mark the break point: */ breakPtr=cPtr; /* Skip whitespace: */ while(isspace(*cPtr)&&*cPtr!='\0') ++cPtr; } while(cPtr-linePtr<40&&*breakPtr!='\n'&&*breakPtr!='\0'); /* Add the current line: */ new GLMotif::Label("messageLine",message,linePtr,breakPtr); /* Go to the beginning of the next line: */ linePtr=breakPtr; while(isspace(*linePtr)&&*linePtr!='\0') ++linePtr; } /* Add an acknowledgment button: */ GLMotif::Margin* buttonMargin=new GLMotif::Margin("ButtonMargin",message,false); buttonMargin->setAlignment(GLMotif::Alignment::RIGHT); GLMotif::Button* okButton=new GLMotif::Button("OkButton",buttonMargin,messageLevel<Warning?"Gee, thanks":messageLevel<Error?"Alright then":"Darn it!"); okButton->getSelectCallbacks().add(closeMessageDialog); buttonMargin->manageChild(); message->manageChild(); /* Show the popup window: */ popupPrimaryWidget(messageDialog); }
void SketchingTool::loadCurvesOKCallback(GLMotif::FileSelectionDialog::OKCallbackData* cbData) { /* Deactivate the tool just in case: */ active=false; /* Delete all curves: */ for(std::vector<Curve*>::iterator cIt=curves.begin();cIt!=curves.end();++cIt) delete *cIt; curves.clear(); try { /* Open the curve file: */ Comm::ClusterFileCharacterSource curvesFile(cbData->selectedFileName.c_str(),openPipe()); Misc::ValueSource curvesSource(curvesFile); curvesSource.setPunctuation(',',true); /* Read the curve file header: */ if(!curvesSource.isString("Vrui Curve Editor Tool Curve File")) Misc::throwStdErr("SketchingTool::loadCurvesOKCallback: File %s is not a curve file",cbData->selectedFileName.c_str()); /* Read all curvesSource: */ unsigned int numCurves=curvesSource.readUnsignedInteger(); for(unsigned int curveIndex=0;curveIndex<numCurves;++curveIndex) { /* Create a new curve: */ Curve* c=new Curve; /* Read the curve's line width and color: */ c->lineWidth=GLfloat(curvesSource.readNumber()); if(curvesSource.readChar()!=',') Misc::throwStdErr("SketchingTool::loadCurvesOKCallback: File %s is not a curve file",cbData->selectedFileName.c_str()); for(int i=0;i<3;++i) c->color[i]=Curve::Color::Scalar(curvesSource.readUnsignedInteger()); c->color[3]=Curve::Color::Scalar(255); /* Read the curve's control points: */ unsigned int numControlPoints=curvesSource.readUnsignedInteger(); for(unsigned int controlPointIndex=0;controlPointIndex<numControlPoints;++controlPointIndex) { Curve::ControlPoint cp; cp.t=Scalar(curvesSource.readNumber()); if(curvesSource.readChar()!=',') Misc::throwStdErr("SketchingTool::loadCurvesOKCallback: File %s is not a curve file",cbData->selectedFileName.c_str()); for(int i=0;i<3;++i) cp.pos[i]=Point::Scalar(curvesSource.readNumber()); c->controlPoints.push_back(cp); } /* Store the curve: */ curves.push_back(c); } } catch(std::runtime_error err) { /* Ignore the error */ } /* Destroy the file selection dialog: */ getWidgetManager()->deleteWidget(cbData->fileSelectionDialog); }