void SelectionPlugin::onMouseButtonRelease( const MouseButtonEvent& event ) { if( event.button != MouseButton::Left ) return; SceneDocument* sceneDocument = (SceneDocument*) editor->getDocument(); sceneDocument->getRenderWindow()->setCursorCapture(false); editor->getDocument()->getWindow()->flagRedraw(); SelectionOperation* selection = nullptr; if(selections->dragRectangle) selection = processDragSelection(event); else selection = processSelection(event); if( !selection ) return; const SelectionCollection& selected = selections->getSelections(); // Prevent duplication of selection events. if( selected.isSame(selection->selections) ) { LogDebug("Ignoring duplicated selection"); Deallocate(selection); return; } selection->redo(); UndoManager* undoManager = sceneDocument->getUndoManager(); undoManager->registerOperation(selection); }
void GuiRoadEditorCtrl::submitUndo( const UTF8 *name ) { // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { Con::errorf( "GuiRoadEditorCtrl::submitUndo() - EUndoManager not found!" ); return; } // Setup the action. GuiRoadEditorUndoAction *action = new GuiRoadEditorUndoAction( name ); action->mObjId = mSelRoad->getId(); action->mBreakAngle = mSelRoad->mBreakAngle; action->mMaterialName = mSelRoad->mMaterialName; action->mSegmentsPerBatch = mSelRoad->mSegmentsPerBatch; action->mTextureLength = mSelRoad->mTextureLength; action->mRoadEditor = this; for( U32 i = 0; i < mSelRoad->mNodes.size(); i++ ) { action->mNodes.push_back( mSelRoad->mNodes[i] ); } undoMan->addAction( action ); }
void GuiDecalEditorCtrl::deleteSelectedDecal() { if ( !mSELDecal ) return; // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { Con::errorf( "GuiMeshRoadEditorCtrl::on3DMouseDown() - EUndoManager not found!" ); return; } // Create the UndoAction. DIDeleteUndoAction *action = new DIDeleteUndoAction("Delete Decal"); action->deleteDecal( *mSELDecal ); action->mEditor = this; // Submit it. undoMan->addAction( action ); if ( isMethod( "onDeleteInstance" ) ) { char buffer[512]; dSprintf(buffer, 512, "%i", mSELDecal->mId); Con::executef( this, "onDeleteInstance", String(buffer).c_str(), mSELDecal->mDataBlock->lookupName.c_str() ); } gDecalManager->removeDecal( mSELDecal ); mSELDecal = NULL; }
bool Object::destroyRenderer(qlib::uid_t uid) { // get renderer ptr/check consistency rendtab_t::iterator i = m_rendtab.find(uid); if (i==m_rendtab.end()) return false; RendererPtr pRend = i->second; ScenePtr pScene = getScene(); if (pScene.isnull() || pRend.isnull()) { LOG_DPRINTLN("Object::destroyRenderer> fatal error pScene or pRend is NULL!"); return false; } // detach renderer from the view-related resources (DL, VBO, etc) pRend->unloading(); // Detach the parent scene from the renderer event source pRend->removeListener(pScene.get()); // Fire the SCE_REND_REMOVING Event, before removing the renderer { MB_DPRINTLN("Object> Firing SCE_REND_REMOVING event..."); SceneEvent ev; ev.setType(SceneEvent::SCE_REND_REMOVING); ev.setSource(getSceneID()); ev.setTarget(pRend->getUID()); pScene->fireSceneEvent(ev); } // remove the rend from the scene's cache list pScene->removeRendCache(pRend); // 2012/9/30 // Detach the rend from obj HERE is very important!! // (This call remove the rend from object's event listener list. // Otherwise, deleted ptr will remain in the listener list, and thus cause crash!!) qlib::uid_t objid = pRend->detachObj(); // MB_ASSERT(objid==this->m_uid); // 2012/9/30 // Setting scene ID to null will cause removing pRend from the scene's listener list // (Without this, deleted ptr will remain in scene's listener list, after clearing the UNDO data!!) pRend->setSceneID(qlib::invalid_uid); // Remove from the renderer table m_rendtab.erase(i); // Record undo/redo info UndoManager *pUM = pScene->getUndoMgr(); if (pUM->isOK()) { ObjLoadEditInfo *pPEI = MB_NEW ObjLoadEditInfo; pPEI->setupRendDestroy(getUID(), pRend); pUM->addEditInfo(pPEI); } return true; }
bool UndoTransaction::commit() { if (!m_data) return false; TransactionData* data = static_cast<TransactionData*>(m_data.data()); UndoManager* UM = data->UM; int stackLevel = data->stackLevel; if (!UM->undoEnabled_) { cancel(); return false; } UndoObject *tmpu = UM->transactions_.at(stackLevel)->transactionObject; TransactionState *tmps = UM->transactions_.at(stackLevel)->transactionState; switch (m_data->m_status) { case Transaction::STATE_OPEN: // qDebug() << "UndoManager::commitTransaction" << data << data->transactionObject->getUName() << data->transactionState->getName() << stackLevel; m_data->m_status = Transaction::STATE_COMMITTED; // brutal for now: assert (stackLevel + 1 == signed(UM->transactions_.size())); if (stackLevel < signed(UM->transactions_.size())) { UM->transactions_.erase(UM->transactions_.begin() + stackLevel); } if (tmps->sizet() > 0) // are there any actions inside the committed transaction { if (tmps->getName().isEmpty()) tmps->useActionName(); UM->action(tmpu, tmps); } // if not just delete objects else { delete tmpu; tmpu = 0; delete tmps; tmps = 0; } return true; break; case STATE_WILLFAIL: return cancel(); break; default: // qDebug() << "UndoManager::commitTransaction ** already closed **"; // nothing break; } return false; }
void GuiDecalEditorCtrl::retargetDecalDatablock( String dbFrom, String dbTo ) { DecalData * ptrFrom = dynamic_cast<DecalData*> ( Sim::findObject(dbFrom.c_str()) ); DecalData * ptrTo = dynamic_cast<DecalData*> ( Sim::findObject(dbTo.c_str()) ); if( !ptrFrom || !ptrTo ) return; // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { Con::errorf( "GuiMeshRoadEditorCtrl::on3DMouseDown() - EUndoManager not found!" ); return; } // Create the UndoAction. DBRetargetUndoAction *action = new DBRetargetUndoAction("Retarget Decal Datablock"); action->mEditor = this; action->mDBFromId = ptrFrom->getId(); action->mDBToId = ptrTo->getId(); Vector<DecalInstance*> mDecalQueue; Vector<DecalInstance *>::iterator iter; mDecalQueue.clear(); const Vector<DecalSphere*> &grid = gDecalManager->getDecalDataFile()->getSphereList(); for ( U32 i = 0; i < grid.size(); i++ ) { const DecalSphere *decalSphere = grid[i]; mDecalQueue.merge( decalSphere->mItems ); } for ( iter = mDecalQueue.begin();iter != mDecalQueue.end();iter++ ) { if( !(*iter) ) continue; if( (*iter)->mDataBlock->lookupName.compare( dbFrom ) == 0 ) { if( (*iter)->mId != -1 ) { action->retargetDecal((*iter)); (*iter)->mDataBlock = ptrTo; forceRedraw((*iter)); } } } undoMan->addAction( action ); }
void ForestTool::_submitUndo( UndoAction *action ) { AssertFatal( action, "ForestTool::_submitUndo() - No undo action!" ); // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { Con::errorf( "ForestTool::_submitUndo() - EUndoManager not found!" ); return; } undoMan->addAction( action ); mEditor->updateCollision(); }
// ApplyChain returns true on success, false otherwise. // Any error reporting to the user has already been done. bool BatchCommands::ApplyChain(const wxString & filename) { mFileName = filename; unsigned int i; bool res = true; mAbort = false; for (i = 0; i < mCommandChain.GetCount(); i++) { if (!ApplyCommandInBatchMode(mCommandChain[i], mParamsChain[i]) || mAbort) { res = false; break; } } mFileName.Empty(); AudacityProject *proj = GetActiveProject(); if (!res) { if(proj) { // Chain failed or was cancelled; revert to the previous state UndoManager *um = proj->GetUndoManager(); proj->SetStateTo(um->GetCurrentState()); } return false; } // Chain was successfully applied; save the new project state wxString longDesc, shortDesc; wxString name = gPrefs->Read(wxT("/Batch/ActiveChain"), wxEmptyString); if (name.IsEmpty()) { longDesc = wxT("Applied batch chain"); shortDesc = wxT("Apply chain"); } else { longDesc = wxString::Format(wxT("Applied batch chain '%s'"), name.c_str()); shortDesc = wxString::Format(wxT("Apply '%s'"), name.c_str()); } if (!proj) return false; proj->PushState(longDesc, shortDesc); return true; }
void GuiRiverEditorCtrl::deleteSelectedRiver( bool undoAble ) { AssertFatal( mSelRiver != NULL, "GuiRiverEditorCtrl::deleteSelectedRiver() - No River IS selected" ); // Not undoAble? Just delete it. if ( !undoAble ) { mSelRiver->deleteObject(); mIsDirty = true; Con::executef( this, "onRiverSelected" ); mSelNode = -1; return; } // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { // Couldn't find it? Well just delete the River. Con::errorf( "GuiRiverEditorCtrl::on3DMouseDown() - EUndoManager not found!" ); return; } else { // Create the UndoAction. MEDeleteUndoAction *action = new MEDeleteUndoAction("Deleted River"); action->deleteObject( mSelRiver ); mIsDirty = true; // Submit it. undoMan->addAction( action ); } // ScriptCallback with 'NULL' parameter for no River currently selected. Con::executef( this, "onRiverSelected" ); // Clear the SelectedNode (it has been deleted along with the River). setSelectedNode( -1 ); mSelNode = -1; // SelectedRiver is a SimObjectPtr and will be NULL automatically. }
void ForestEditorCtrl::deleteMeshSafe( ForestItemData *mesh ) { UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { Con::errorf( "ForestEditorCtrl::deleteMeshSafe() - EUndoManager not found." ); return; } // CompoundUndoAction which will delete the ForestItemData, ForestItem(s), and ForestBrushElement(s). CompoundUndoAction *compoundAction = new CompoundUndoAction( "Delete Forest Mesh" ); // Find ForestItem(s) referencing this datablock and add their deletion // to the undo action. if ( mForest ) { Vector<ForestItem> foundItems; mForest->getData()->getItems( mesh, &foundItems ); ForestDeleteUndoAction *itemAction = new ForestDeleteUndoAction( mForest->getData(), this ); itemAction->removeItem( foundItems ); compoundAction->addAction( itemAction ); } // Find ForestBrushElement(s) referencing this datablock. SimGroup *brushGroup = ForestBrush::getGroup(); sKey = mesh; Vector<SimObject*> foundElements; brushGroup->findObjectByCallback( &findMeshReferences, foundElements ); // Add UndoAction to delete the ForestBrushElement(s) and the ForestItemData. MEDeleteUndoAction *elementAction = new MEDeleteUndoAction(); elementAction->deleteObject( foundElements ); elementAction->deleteObject( mesh ); // Add compound action to the UndoManager. Done. undoMan->addAction( compoundAction ); updateCollision(); }
void EffectLayer::MoveAllSelectedEffects(int deltaMS, UndoManager& undo_mgr) { std::unique_lock<std::recursive_mutex> locker(lock); for(int i=0; i<mEffects.size();i++) { if(mEffects[i]->GetSelected() == EFFECT_LT_SELECTED && mEffects[i]->GetTagged()) { if( undo_mgr.GetCaptureUndo() ) { undo_mgr.CaptureEffectToBeMoved( mParentElement->GetName(), mIndex, mEffects[i]->GetID(), mEffects[i]->GetStartTimeMS(), mEffects[i]->GetEndTimeMS() ); } mEffects[i]->SetStartTimeMS( mEffects[i]->GetStartTimeMS() + deltaMS); } else if(mEffects[i]->GetSelected() == EFFECT_RT_SELECTED && mEffects[i]->GetTagged()) { if( undo_mgr.GetCaptureUndo() ) { undo_mgr.CaptureEffectToBeMoved( mParentElement->GetName(), mIndex, mEffects[i]->GetID(), mEffects[i]->GetStartTimeMS(), mEffects[i]->GetEndTimeMS() ); } mEffects[i]->SetEndTimeMS( mEffects[i]->GetEndTimeMS() + deltaMS); } else if(mEffects[i]->GetSelected() == EFFECT_SELECTED && mEffects[i]->GetTagged()) { if( undo_mgr.GetCaptureUndo() ) { undo_mgr.CaptureEffectToBeMoved( mParentElement->GetName(), mIndex, mEffects[i]->GetID(), mEffects[i]->GetStartTimeMS(), mEffects[i]->GetEndTimeMS() ); } mEffects[i]->SetStartTimeMS( mEffects[i]->GetStartTimeMS() + deltaMS); mEffects[i]->SetEndTimeMS( mEffects[i]->GetEndTimeMS() + deltaMS); } mEffects[i]->SetTagged(false); } }
bool Object::registerRendererImpl(RendererPtr rrend) { bool res = m_rendtab.insert(rendtab_t::value_type(rrend->getUID(), rrend)).second; if (!res) return false; rrend->setSceneID(getSceneID()); rrend->attachObj(this->m_uid); ScenePtr pScene = getScene(); if (pScene.isnull()) return true; // add the new rend to the scene's cache list pScene->addRendCache(rrend); // The scene observes events from the new renderer //rrend->addPropListener(pScene.get()); rrend->addListener(pScene.get()); // Fire the SCE_REND_ADDED Event { MB_DPRINTLN("Object> Firing SCE_REND_ADDED event..."); SceneEvent ev; ev.setType(SceneEvent::SCE_REND_ADDED); ev.setSource(getSceneID()); ev.setTarget(rrend->getUID()); pScene->fireSceneEvent(ev); } // Record undo/redo info UndoManager *pUM = pScene->getUndoMgr(); if (pUM->isOK()) { ObjLoadEditInfo *pPEI = MB_NEW ObjLoadEditInfo; pPEI->setupRendCreate(getUID(), rrend); pUM->addEditInfo(pPEI); } return true; }
void GuiRoadEditorCtrl::deleteSelectedRoad( bool undoAble ) { AssertFatal( mSelRoad != NULL, "GuiRoadEditorCtrl::deleteSelectedRoad() - No road IS selected" ); // Not undo-able? Just delete it. if ( !undoAble ) { DecalRoad *lastRoad = mSelRoad; setSelectedRoad(NULL); lastRoad->deleteObject(); mIsDirty = true; return; } // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { // Couldn't find it? Well just delete the road. Con::errorf( "GuiRoadEditorCtrl::on3DMouseDown() - EUndoManager not found!" ); return; } else { DecalRoad *lastRoad = mSelRoad; setSelectedRoad(NULL); // Create the UndoAction. MEDeleteUndoAction *action = new MEDeleteUndoAction("Deleted Road"); action->deleteObject( lastRoad ); mIsDirty = true; // Submit it. undoMan->addAction( action ); } }
void SceneStructureWindow::SetShownScene(const ScenePtr &newScene) { if (!scene.expired() && newScene == scene.lock()) return; ScenePtr previous = ShownScene(); if (previous) { disconnect(previous.get()); Clear(); } scene = newScene; treeWidget->SetScene(newScene); if (newScene) { // Now that treeWidget has scene, it also has UndoManager. UndoManager *undoMgr = treeWidget->GetUndoManager(); undoButton_->setMenu(undoMgr->UndoMenu()); redoButton_->setMenu(undoMgr->RedoMenu()); connect(undoMgr, SIGNAL(CanUndoChanged(bool)), this, SLOT(SetUndoEnabled(bool)), Qt::UniqueConnection); connect(undoMgr, SIGNAL(CanRedoChanged(bool)), this, SLOT(SetRedoEnabled(bool)), Qt::UniqueConnection); connect(undoButton_, SIGNAL(clicked()), undoMgr, SLOT(Undo()), Qt::UniqueConnection); connect(redoButton_, SIGNAL(clicked()), undoMgr, SLOT(Redo()), Qt::UniqueConnection); Scene* s = ShownScene().get(); connect(s, SIGNAL(EntityAcked(Entity *, entity_id_t)), SLOT(AckEntity(Entity *, entity_id_t))); connect(s, SIGNAL(EntityCreated(Entity *, AttributeChange::Type)), SLOT(AddEntity(Entity *))); connect(s, SIGNAL(EntityTemporaryStateToggled(Entity *, AttributeChange::Type)), SLOT(UpdateEntityTemporaryState(Entity *))); connect(s, SIGNAL(EntityRemoved(Entity *, AttributeChange::Type)), SLOT(RemoveEntity(Entity *))); connect(s, SIGNAL(ComponentAdded(Entity *, IComponent *, AttributeChange::Type)), SLOT(AddComponent(Entity *, IComponent *))); connect(s, SIGNAL(ComponentRemoved(Entity *, IComponent *, AttributeChange::Type)), SLOT(RemoveComponent(Entity *, IComponent *))); connect(s, SIGNAL(SceneCleared(Scene*)), SLOT(Clear())); Populate(); } }
void EffectLayer::DeleteSelectedEffects(UndoManager& undo_mgr) { std::unique_lock<std::recursive_mutex> locker(lock); for (std::vector<Effect*>::iterator it = mEffects.begin(); it != mEffects.end(); it++) { if ((*it)->GetSelected() != EFFECT_NOT_SELECTED) { IncrementChangeCount((*it)->GetStartTimeMS(), (*it)->GetEndTimeMS()); undo_mgr.CaptureEffectToBeDeleted( mParentElement->GetName(), mIndex, (*it)->GetEffectName(), (*it)->GetSettingsAsString(), (*it)->GetPaletteAsString(), (*it)->GetStartTimeMS(), (*it)->GetEndTimeMS(), (*it)->GetSelected(), (*it)->GetProtected() ); } } mEffects.erase(std::remove_if(mEffects.begin(), mEffects.end(),ShouldDeleteSelected),mEffects.end()); }
void GuiDecalEditorCtrl::deleteDecalDatablock( String lookupName ) { DecalData * datablock = dynamic_cast<DecalData*> ( Sim::findObject(lookupName.c_str()) ); if( !datablock ) return; // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { Con::errorf( "GuiMeshRoadEditorCtrl::on3DMouseDown() - EUndoManager not found!" ); return; } // Create the UndoAction. DBDeleteUndoAction *action = new DBDeleteUndoAction("Delete Decal Datablock"); action->mEditor = this; action->mDatablockId = datablock->getId(); Vector<DecalInstance*> mDecalQueue; Vector<DecalInstance *>::iterator iter; mDecalQueue.clear(); const Vector<DecalSphere*> &grid = gDecalManager->getDecalDataFile()->getSphereList(); for ( U32 i = 0; i < grid.size(); i++ ) { const DecalSphere *decalSphere = grid[i]; mDecalQueue.merge( decalSphere->mItems ); } for ( iter = mDecalQueue.begin();iter != mDecalQueue.end();iter++ ) { if( !(*iter) ) continue; if( (*iter)->mDataBlock->lookupName.compare( lookupName ) == 0 ) { if( (*iter)->mId != -1 ) { //make sure to call onDeleteInstance as well if ( isMethod( "onDeleteInstance" ) ) { char buffer[512]; dSprintf(buffer, 512, "%i", (*iter)->mId); Con::executef( this, "onDeleteInstance", String(buffer).c_str(), (*iter)->mDataBlock->lookupName.c_str() ); } action->deleteDecal( *(*iter) ); if( mSELDecal == (*iter) ) mSELDecal = NULL; if( mHLDecal == (*iter) ) mHLDecal = NULL; } gDecalManager->removeDecal( (*iter) ); } } undoMan->addAction( action ); mCurrentDecalData = NULL; }
void BatchProcessDialog::OnApplyToFiles(wxCommandEvent &event) { long item = mChains->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (item == -1) { wxMessageBox(_("No chain selected")); return; } wxString name = mChains->GetItemText(item); gPrefs->Write(wxT("/Batch/ActiveChain"), name); AudacityProject *project = GetActiveProject(); if (!project->GetIsEmpty()) { wxMessageBox(_("Please save and close the current project first.")); return; } wxString path = gPrefs->Read(wxT("/DefaultOpenPath"), ::wxGetCwd()); wxString prompt = project->GetCleanSpeechMode() ? _("Select vocal file(s) for batch CleanSpeech Chain...") : _("Select file(s) for batch processing..."); wxString fileSelector = project->GetCleanSpeechMode() ? _("Vocal files (*.wav;*.mp3)|*.wav;*.mp3|WAV files (*.wav)|*.wav|MP3 files (*.mp3)|*.mp3") : _("All files (*.*)|*.*|WAV files (*.wav)|*.wav|AIFF files (*.aif)|*.aif|AU files (*.au)|*.au|MP3 files (*.mp3)|*.mp3|Ogg Vorbis files (*.ogg)|*.ogg|FLAC files (*.flac)|*.flac" ); FileDialog dlog(this, prompt, path, wxT(""), fileSelector, wxFD_OPEN | wxFD_MULTIPLE | wxRESIZE_BORDER); if (dlog.ShowModal() != wxID_OK) { return; } wxArrayString files; dlog.GetPaths(files); files.Sort(); wxDialog d(this, wxID_ANY, GetTitle()); ShuttleGui S(&d, eIsCreating); S.StartVerticalLay(false); { S.StartStatic(_("Applying..."), 1); { wxImageList *imageList = new wxImageList(9, 16); imageList->Add(wxIcon(empty_9x16_xpm)); imageList->Add(wxIcon(arrow_xpm)); S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_SINGLE_SEL); mList = S.AddListControlReportMode(); mList->AssignImageList(imageList, wxIMAGE_LIST_SMALL); mList->InsertColumn(0, _("File"), wxLIST_FORMAT_LEFT); } S.EndStatic(); S.StartHorizontalLay(wxCENTER, false); { S.Id(wxID_CANCEL).AddButton(_("&Cancel")); } S.EndHorizontalLay(); } S.EndVerticalLay(); int i; for (i = 0; i < (int)files.GetCount(); i++ ) { mList->InsertItem(i, files[i], i == 0); } // Set the column size for the files list. mList->SetColumnWidth(0, wxLIST_AUTOSIZE); int width = mList->GetColumnWidth(0); wxSize sz = mList->GetClientSize(); if (width > sz.GetWidth() && width < 500) { sz.SetWidth(width); mList->SetInitialSize(sz); } d.Layout(); d.Fit(); d.SetSizeHints(d.GetSize()); d.CenterOnScreen(); d.Move(-1, 0); d.Show(); Hide(); mBatchCommands.ReadChain(name); for (i = 0; i < (int)files.GetCount(); i++) { wxWindowDisabler wd(&d); if (i > 0) { //Clear the arrow in previous item. mList->SetItemImage(i - 1, 0, 0); } mList->SetItemImage(i, 1, 1); mList->EnsureVisible(i); project->OnRemoveTracks(); project->Import(files[i]); project->OnSelectAll(); if (!mBatchCommands.ApplyChain()) { break; } if (!d.IsShown() || mAbort) { break; } UndoManager *um = project->GetUndoManager(); um->ClearStates(); } project->OnRemoveTracks(); }
void GuiDecalEditorCtrl::on3DMouseDragged(const Gui3DMouseEvent & event) { if ( !mSELDecal ) return; // Doing a drag copy of the decal? if ( event.modifier & SI_SHIFT && !mPerformedDragCopy ) { mPerformedDragCopy = true; DecalInstance *newDecal = gDecalManager->addDecal( mSELDecal->mPosition, mSELDecal->mNormal, 0.0f, mSELDecal->mDataBlock, 1.0f, -1, PermanentDecal | SaveDecal ); newDecal->mTangent = mSELDecal->mTangent; newDecal->mSize = mSELDecal->mSize; newDecal->mTextureRectIdx = mSELDecal->mTextureRectIdx; // TODO: This is crazy... we should move this sort of tracking // inside of the decal manager... IdDecal flag maybe or just a // byproduct of PermanentDecal? // newDecal->mId = gDecalManager->mDecalInstanceVec.size(); gDecalManager->mDecalInstanceVec.push_back( newDecal ); selectDecal( newDecal ); // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( Sim::findObject( "EUndoManager", undoMan ) ) { // Create the UndoAction. DICreateUndoAction *action = new DICreateUndoAction("Create Decal"); action->addDecal( *mSELDecal ); action->mEditor = this; undoMan->addAction( action ); if ( isMethod( "onCreateInstance" ) ) { char buffer[512]; dSprintf( buffer, 512, "%i", mSELDecal->mId ); Con::executef( this, "onCreateInstance", buffer, mSELDecal->mDataBlock->lookupName.c_str()); } } } // Update the Gizmo. if (mGizmo->getSelection() != Gizmo::None) { mGizmo->on3DMouseDragged( event ); // Pull out the Gizmo transform // and position. const MatrixF &gizmoMat = mGizmo->getTransform(); const Point3F &gizmoPos = gizmoMat.getPosition(); // Get the new projection vector. VectorF upVec, rightVec; gizmoMat.getColumn( 0, &rightVec ); gizmoMat.getColumn( 2, &upVec ); const Point3F &scale = mGizmo->getScale(); // Assign the appropriate changed value back to the decal. if ( mGizmo->getMode() == ScaleMode ) { // Save old size. const F32 oldSize = mSELDecal->mSize; // Set new size. mSELDecal->mSize = ( scale.x + scale.y ) * 0.5f; // See if the decal properly clips/projects at this size. If not, // stick to the old size. mSELEdgeVerts.clear(); if ( !gDecalManager->clipDecal( mSELDecal, &mSELEdgeVerts ) ) mSELDecal->mSize = oldSize; } else if ( mGizmo->getMode() == MoveMode ) mSELDecal->mPosition = gizmoPos; else if ( mGizmo->getMode() == RotateMode ) { mSELDecal->mNormal = upVec; mSELDecal->mTangent = rightVec; } gDecalManager->notifyDecalModified( mSELDecal ); Con::executef( this, "syncNodeDetails" ); } }
void GuiDecalEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event) { mPerformedDragCopy = false; if ( !isFirstResponder() ) setFirstResponder(); bool dblClick = ( event.mouseClickCount > 1 ); // Gather selected decal information RayInfo ri; bool hit = getRayInfo( event, &ri ); Point3F start = event.pos; Point3F end = start + event.vec * 3000.0f; // use visible distance here?? DecalInstance *pDecal = gDecalManager->raycast( start, end ); if( mMode.compare("AddDecalMode") != 0 ) { if ( mSELDecal ) { // If our click hit the gizmo we are done. if ( mGizmo->getSelection() != Gizmo::None ) { mGizmo->on3DMouseDown( event ); char returnBuffer[256]; dSprintf(returnBuffer, sizeof(returnBuffer), "%f %f %f %f %f %f %f", mSELDecal->mPosition.x, mSELDecal->mPosition.y, mSELDecal->mPosition.z, mSELDecal->mTangent.x, mSELDecal->mTangent.y, mSELDecal->mTangent.z, mSELDecal->mSize); Con::executef( this, "prepGizmoTransform", Con::getIntArg(mSELDecal->mId), returnBuffer ); return; } } if ( mHLDecal && pDecal == mHLDecal ) { mHLDecal = NULL; selectDecal( pDecal ); if ( isMethod( "onSelectInstance" ) ) { char idBuf[512]; dSprintf(idBuf, 512, "%i", pDecal->mId); Con::executef( this, "onSelectInstance", String(idBuf).c_str(), pDecal->mDataBlock->lookupName.c_str() ); } return; } else if ( hit && !pDecal) { if ( dblClick ) setMode( String("AddDecalMode"), true ); return; } } else { // If we accidently hit a decal, then bail(probably an accident). If the use hits the decal twice, // then boot them into selection mode and select the decal. if ( mHLDecal && pDecal == mHLDecal ) { if ( dblClick ) { mHLDecal = NULL; selectDecal( pDecal ); if ( isMethod( "onSelectInstance" ) ) { char idBuf[512]; dSprintf(idBuf, 512, "%i", pDecal->mId); Con::executef( this, "onSelectInstance", String(idBuf).c_str(), pDecal->mDataBlock->lookupName.c_str() ); } setMode( String("SelectDecalMode"), true ); } return; } if ( hit && mCurrentDecalData ) // Create a new decal... { U8 flags = PermanentDecal | SaveDecal; DecalInstance *decalInst = gDecalManager->addDecal( ri.point, ri.normal, 0.0f, mCurrentDecalData, 1.0f, -1, flags ); if ( decalInst ) { // Give the decal an id decalInst->mId = gDecalManager->mDecalInstanceVec.size(); gDecalManager->mDecalInstanceVec.push_back(decalInst); selectDecal( decalInst ); // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { Con::errorf( "GuiMeshRoadEditorCtrl::on3DMouseDown() - EUndoManager not found!" ); return; } // Create the UndoAction. DICreateUndoAction *action = new DICreateUndoAction("Create Decal"); action->addDecal( *decalInst ); action->mEditor = this; // Submit it. undoMan->addAction( action ); if ( isMethod( "onCreateInstance" ) ) { char buffer[512]; dSprintf(buffer, 512, "%i", decalInst->mId); Con::executef( this, "onCreateInstance", buffer, decalInst->mDataBlock->lookupName.c_str()); } } return; } } if ( !mSELDecal ) return; }
void GuiRoadEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event) { if ( !isFirstResponder() ) setFirstResponder(); // Get the clicked terrain position. Point3F tPos; if ( !getTerrainPos( event, tPos ) ) return; mouseLock(); // Find any road / node at the clicked position. // TODO: handle overlapping roads/nodes somehow, cycle through them. DecalRoad *roadPtr = NULL; S32 closestNodeIdx = -1; F32 closestDist = F32_MAX; DecalRoad *closestNodeRoad = NULL; // First, find the closest node in any road to the clicked position. for ( SimSetIterator iter(mRoadSet); *iter; ++iter ) { roadPtr = static_cast<DecalRoad*>( *iter ); U32 idx; if ( roadPtr->getClosestNode( tPos, idx ) ) { Point3F nodePos = roadPtr->getNodePosition(idx); F32 dist = ( nodePos - tPos ).len(); if ( dist < closestDist ) { closestNodeIdx = idx; closestDist = dist; closestNodeRoad = roadPtr; } } } // // Second, determine if the screen-space node rectangle // contains the clicked position. bool nodeClicked = false; S32 clickedNodeIdx = -1; if ( closestNodeIdx != -1 ) { Point3F nodePos = closestNodeRoad->getNodePosition( closestNodeIdx ); Point3F temp; project( nodePos, &temp ); Point2I screenPos( temp.x, temp.y ); RectI nodeRect( screenPos - mNodeHalfSize, mNodeHalfSize * 2 ); nodeClicked = nodeRect.pointInRect( event.mousePoint ); if ( nodeClicked ) clickedNodeIdx = closestNodeIdx; } // // Determine the clickedRoad // DecalRoad *clickedRoadPtr = NULL; U32 insertNodeIdx = 0; if ( nodeClicked && (mSelRoad == NULL || closestNodeRoad == mSelRoad) ) { // If a node was clicked, the owning road is always // considered the clicked road. clickedRoadPtr = closestNodeRoad; } else { // check the selected road first if ( mSelRoad != NULL && mSelRoad->containsPoint( tPos, &insertNodeIdx ) ) { clickedRoadPtr = mSelRoad; nodeClicked = false; clickedNodeIdx = -1; } else { // Otherwise, we must ask each road if it contains // the clicked pos. for ( SimSetIterator iter(mRoadSet); *iter; ++iter ) { roadPtr = static_cast<DecalRoad*>( *iter ); if ( roadPtr->containsPoint( tPos, &insertNodeIdx ) ) { clickedRoadPtr = roadPtr; break; } } } } // shortcuts bool dblClick = ( event.mouseClickCount > 1 ); if( dblClick ) { if( mMode == mSelectRoadMode ) { setMode( mAddRoadMode, true ); return; } if( mMode == mAddNodeMode ) { // Delete the node attached to the cursor. deleteSelectedNode(); mMode = mAddRoadMode; return; } } //this check is here in order to bounce back from deleting a whole road with ctrl+z //this check places the editor back into addroadmode if ( mMode == mAddNodeMode ) { if ( !mSelRoad ) mMode = mAddRoadMode; } if ( mMode == mSelectRoadMode ) { // Did not click on a road or a node. if ( !clickedRoadPtr ) { setSelectedRoad( NULL ); setSelectedNode( -1 ); return; } // Clicked on a road that wasn't the currently selected road. if ( clickedRoadPtr != mSelRoad ) { setSelectedRoad( clickedRoadPtr ); setSelectedNode( -1 ); return; } // Clicked on a node in the currently selected road that wasn't // the currently selected node. if ( nodeClicked ) { setSelectedNode( clickedNodeIdx ); return; } // Clicked a position on the currently selected road // that did not contain a node. //U32 newNode = clickedRoadPtr->insertNode( tPos, mDefaultWidth, insertNodeIdx ); //setSelectedNode( newNode ); } else if ( mMode == mAddRoadMode ) { if ( nodeClicked && clickedRoadPtr ) { // A double-click on a node in Normal mode means set AddNode mode. if ( clickedNodeIdx == 0 ) { setSelectedRoad( clickedRoadPtr ); setSelectedNode( clickedNodeIdx ); mAddNodeIdx = clickedNodeIdx; mMode = mAddNodeMode; mSelNode = mSelRoad->insertNode( tPos, mDefaultWidth, mAddNodeIdx ); mIsDirty = true; return; } else if ( clickedNodeIdx == clickedRoadPtr->mNodes.size() - 1 ) { setSelectedRoad( clickedRoadPtr ); setSelectedNode( clickedNodeIdx ); mAddNodeIdx = U32_MAX; mMode = mAddNodeMode; mSelNode = mSelRoad->addNode( tPos, mDefaultWidth ); mIsDirty = true; setSelectedNode( mSelNode ); return; } } DecalRoad *newRoad = new DecalRoad; newRoad->mMaterialName = mMaterialName; newRoad->registerObject(); // Add to MissionGroup SimGroup *missionGroup; if ( !Sim::findObject( "MissionGroup", missionGroup ) ) Con::errorf( "GuiDecalRoadEditorCtrl - could not find MissionGroup to add new DecalRoad" ); else missionGroup->addObject( newRoad ); newRoad->insertNode( tPos, mDefaultWidth, 0 ); U32 newNode = newRoad->insertNode( tPos, mDefaultWidth, 1 ); // Always add to the end of the road, the first node is the start. mAddNodeIdx = U32_MAX; setSelectedRoad( newRoad ); setSelectedNode( newNode ); mMode = mAddNodeMode; // Disable the hover node while in addNodeMode, we // don't want some random node enlarged. mHoverNode = -1; // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { Con::errorf( "GuiRoadEditorCtrl::on3DMouseDown() - EUndoManager not found!" ); return; } // Create the UndoAction. MECreateUndoAction *action = new MECreateUndoAction("Create Road"); action->addObject( newRoad ); // Submit it. undoMan->addAction( action ); //send a callback to script after were done here if one exists if ( isMethod( "onRoadCreation" ) ) Con::executef( this, "onRoadCreation" ); return; } else if ( mMode == mAddNodeMode ) { // Oops the road got deleted, maybe from an undo action? // Back to NormalMode. if ( mSelRoad ) { // A double-click on a node in Normal mode means set AddNode mode. if ( clickedNodeIdx == 0 ) { submitUndo( "Add Node" ); mAddNodeIdx = clickedNodeIdx; mMode = mAddNodeMode; mSelNode = mSelRoad->insertNode( tPos, mDefaultWidth, mAddNodeIdx ); mIsDirty = true; setSelectedNode( mSelNode ); return; } else { if( clickedRoadPtr && clickedNodeIdx == clickedRoadPtr->mNodes.size() - 1 ) { submitUndo( "Add Node" ); mAddNodeIdx = U32_MAX; mMode = mAddNodeMode; mSelNode = mSelRoad->addNode( tPos, mDefaultWidth ); mIsDirty = true; setSelectedNode( mSelNode ); return; } else { submitUndo( "Insert Node" ); // A single-click on empty space while in // AddNode mode means insert / add a node. //submitUndo( "Add Node" ); //F32 width = mSelRoad->getNodeWidth( mSelNode ); U32 newNode = mSelRoad->insertNode( tPos, mDefaultWidth, mAddNodeIdx); mIsDirty = true; setSelectedNode( newNode ); return; } } } } else if ( mMode == mInsertPointMode && mSelRoad != NULL) { if ( clickedRoadPtr == mSelRoad ) { F32 w0 = mSelRoad->getNodeWidth( insertNodeIdx ); F32 w1 = mSelRoad->getNodeWidth( insertNodeIdx + 1 ); F32 width = ( w0 + w1 ) * 0.5f; submitUndo( "Insert Node" ); U32 newNode = mSelRoad->insertNode( tPos, width, insertNodeIdx + 1); mIsDirty = true; setSelectedNode( newNode ); return; } } else if ( mMode == mRemovePointMode && mSelRoad != NULL) { if ( nodeClicked && clickedRoadPtr == mSelRoad ) { setSelectedNode( clickedNodeIdx ); deleteSelectedNode(); return; } } else if ( mMode == mMovePointMode ) { if ( nodeClicked && clickedRoadPtr == mSelRoad ) { setSelectedNode( clickedNodeIdx ); return; } } else if ( mMode == mScalePointMode ) { if ( nodeClicked && clickedRoadPtr == mSelRoad ) { setSelectedNode( clickedNodeIdx ); return; } } }
void BatchProcessDialog::OnApplyToFiles(wxCommandEvent & WXUNUSED(event)) { long item = mChains->GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (item == -1) { wxMessageBox(_("No chain selected")); return; } wxString name = mChains->GetItemText(item); gPrefs->Write(wxT("/Batch/ActiveChain"), name); gPrefs->Flush(); AudacityProject *project = GetActiveProject(); if (!project->GetIsEmpty()) { wxMessageBox(_("Please save and close the current project first.")); return; } wxString path = gPrefs->Read(wxT("/DefaultOpenPath"), ::wxGetCwd()); wxString prompt = _("Select file(s) for batch processing..."); FormatList l; wxString filter; wxString all; Importer::Get().GetSupportedImportFormats(&l); for (const auto &format : l) { const Format *f = &format; wxString newfilter = f->formatName + wxT("|"); for (size_t i = 0; i < f->formatExtensions.size(); i++) { if (!newfilter.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";"))) newfilter += wxT("*.") + f->formatExtensions[i] + wxT(";"); if (!all.Contains(wxT("*.") + f->formatExtensions[i] + wxT(";"))) all += wxT("*.") + f->formatExtensions[i] + wxT(";"); } newfilter.RemoveLast(1); filter += newfilter; filter += wxT("|"); } all.RemoveLast(1); filter.RemoveLast(1); wxString mask = _("All files|*|All supported files|") + all + wxT("|") + filter; wxString type = gPrefs->Read(wxT("/DefaultOpenType"),mask.BeforeFirst(wxT('|'))); // Convert the type to the filter index int index = mask.First(type + wxT("|")); if (index == wxNOT_FOUND) { index = 0; } else { index = mask.Left(index).Freq(wxT('|')) / 2; if (index < 0) { index = 0; } } FileDialog dlog(this, prompt, path, wxT(""), mask, wxFD_OPEN | wxFD_MULTIPLE | wxRESIZE_BORDER); dlog.SetFilterIndex(index); if (dlog.ShowModal() != wxID_OK) { return; } wxArrayString files; dlog.GetPaths(files); files.Sort(); wxDialog * pD = safenew wxDialog(this, wxID_ANY, GetTitle()); pD->SetName(pD->GetTitle()); ShuttleGui S(pD, eIsCreating); S.StartVerticalLay(false); { S.StartStatic(_("Applying..."), 1); { wxImageList *imageList = new wxImageList(9, 16); imageList->Add(wxIcon(empty9x16_xpm)); imageList->Add(wxIcon(arrow_xpm)); S.SetStyle(wxSUNKEN_BORDER | wxLC_REPORT | wxLC_HRULES | wxLC_VRULES | wxLC_SINGLE_SEL); mList = S.Id(CommandsListID).AddListControlReportMode(); mList->AssignImageList(imageList, wxIMAGE_LIST_SMALL); mList->InsertColumn(0, _("File"), wxLIST_FORMAT_LEFT); } S.EndStatic(); S.StartHorizontalLay(wxCENTER, false); { S.Id(wxID_CANCEL).AddButton(_("&Cancel")); } S.EndHorizontalLay(); } S.EndVerticalLay(); int i; for (i = 0; i < (int)files.GetCount(); i++ ) { mList->InsertItem(i, files[i], i == 0); } // Set the column size for the files list. mList->SetColumnWidth(0, wxLIST_AUTOSIZE); int width = mList->GetColumnWidth(0); wxSize sz = mList->GetClientSize(); if (width > sz.GetWidth() && width < 500) { sz.SetWidth(width); mList->SetInitialSize(sz); } pD->Layout(); pD->Fit(); pD->SetSizeHints(pD->GetSize()); pD->CenterOnScreen(); pD->Move(-1, 0); pD->Show(); Hide(); mBatchCommands.ReadChain(name); for (i = 0; i < (int)files.GetCount(); i++) { wxWindowDisabler wd(pD); if (i > 0) { //Clear the arrow in previous item. mList->SetItemImage(i - 1, 0, 0); } mList->SetItemImage(i, 1, 1); mList->EnsureVisible(i); project->Import(files[i]); project->OnSelectAll(); if (!mBatchCommands.ApplyChain()) { break; } if (!pD->IsShown() || mAbort) { break; } UndoManager *um = project->GetUndoManager(); um->ClearStates(); project->OnSelectAll(); project->OnRemoveTracks(); } project->OnRemoveTracks(); // Under Linux an EndModal() here crashes (Bug #1221). // But sending a close message instead is OK. #if !defined(__WXMAC__) wxCloseEvent Evt; Evt.SetId( wxID_OK ); Evt.SetEventObject( this); ProcessWindowEvent( Evt ); #else EndModal(wxID_OK); #endif // Raise myself again, and the parent window with me Show(); }
bool PathFinderPlugin::run(ScribusDoc* doc, QString) { ScribusDoc* currDoc = doc; if (currDoc == 0) currDoc = ScCore->primaryMainWindow()->doc; if (currDoc->m_Selection->count() <= 1) return true; //<<#9046 UndoTransaction* activeTransaction = NULL; UndoManager* undoManager = UndoManager::instance(); if (UndoManager::undoEnabled()) activeTransaction = new UndoTransaction(undoManager->beginTransaction(Um::SelectionGroup, Um::IDocument, Um::PathOperation, "", Um::IPolygon)); //>>#9046 PageItem *Item1 = currDoc->m_Selection->itemAt(0); PageItem *Item2 = currDoc->m_Selection->itemAt(1); PathFinderDialog *dia = new PathFinderDialog(currDoc->scMW(), currDoc, Item1, Item2); if (dia->exec()) { int opMode=dia->opMode; if (dia->keepItem1) { PageItem *newItem; if (dia->swapped) { newItem = new PageItem_Polygon(*Item2); newItem->setSelected(false); currDoc->Items->insert(currDoc->Items->indexOf(Item2), newItem); } else { newItem = new PageItem_Polygon(*Item1); newItem->setSelected(false); currDoc->Items->insert(currDoc->Items->indexOf(Item1), newItem); } if (UndoManager::undoEnabled()) { ScItemState<PageItem*> *is = new ScItemState<PageItem*>("Create PageItem"); is->set("CREATE_ITEM", "create_item"); is->setItem(newItem); UndoObject *target = currDoc->Pages->at(Item1->OwnPage); undoManager->action(target, is); } } if (dia->keepItem2) { PageItem *newItem; if (dia->swapped) { newItem = new PageItem_Polygon(*Item1); newItem->setSelected(false); currDoc->Items->insert(currDoc->Items->indexOf(Item1), newItem); } else { newItem = new PageItem_Polygon(*Item2); newItem->setSelected(false); currDoc->Items->insert(currDoc->Items->indexOf(Item2), newItem); } if (UndoManager::undoEnabled()) { ScItemState<PageItem*> *is = new ScItemState<PageItem*>("Create PageItem"); is->set("CREATE_ITEM", "create_item"); is->setItem(newItem); UndoObject *target = currDoc->Pages->at(Item1->OwnPage); undoManager->action(target, is); } } if (opMode != 4) { PageItem *currItem; QPainterPath path; FPointArray points; if (dia->targetColor == 0) { currItem = Item1; if (dia->swapped) { currItem = Item2; currItem->setXYPos(Item1->xPos(), Item1->yPos()); currItem->setRotation(0.0); } } else { if (dia->swapped) currItem = Item1; else { currItem = Item2; currItem->setXYPos(Item1->xPos(), Item1->yPos()); currItem->setRotation(0.0); } } path = dia->result; points.fromQPainterPath(path); //<<#9046 FPointArray oldPOLine=currItem->PoLine; FPointArray oldContourLine=currItem->ContourLine; ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >* state = NULL; if (UndoManager::undoEnabled()) { state = new ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >(Um::PathOperation); state->set("PATH_OPERATION", "path_operation"); state->set("PATH_OP_OLD_FRAME", currItem->Frame); state->set("PATH_OP_OLD_CLIPEDITED", currItem->ClipEdited); state->set("PATH_OP_OLD_FRAMETYPE", currItem->FrameType); state->set("PATH_OP_OLD_OLDB2", currItem->OldB2); state->set("PATH_OP_OLD_OLDH2", currItem->OldH2); state->set("PATH_OP_NEW_FRAME", false); state->set("PATH_OP_NEW_CLIPEDITED", true); state->set("PATH_OP_NEW_FRAMETYPE", 3); } //>>#9046 currItem->PoLine = points; currItem->Frame = false; currItem->ClipEdited = true; currItem->FrameType = 3; currDoc->AdjustItemSize(currItem); currItem->OldB2 = currItem->width(); currItem->OldH2 = currItem->height(); currItem->updateClip(); currItem->ContourLine = currItem->PoLine.copy(); //<<#9046 if (UndoManager::undoEnabled()) { state->set("PATH_OP_NEW_OLDB2", currItem->OldB2); state->set("PATH_OP_NEW_OLDH2", currItem->OldH2); state->setItem(QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> >(QPair<FPointArray, FPointArray>(oldPOLine, oldContourLine), QPair<FPointArray, FPointArray>(points, currItem->ContourLine))); undoManager->action(currItem, state); } //>>#9046 currDoc->m_Selection->removeItem(currItem); currDoc->itemSelection_DeleteItem(); } else { QPainterPath path; FPointArray points; PageItem *newItem; double i1x = Item1->xPos(); double i1y = Item1->yPos(); path = dia->result; if (!path.isEmpty()) { points.fromQPainterPath(path); //<<#9046 FPointArray oldPOLine=Item1->PoLine; FPointArray oldContourLine=Item1->ContourLine; ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >* state = NULL; if (UndoManager::undoEnabled()) { state = new ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >(Um::PathOperation); state->set("PATH_OPERATION", "path_operation"); state->set("PATH_OP_OLD_FRAME", Item1->Frame); state->set("PATH_OP_OLD_CLIPEDITED", Item1->ClipEdited); state->set("PATH_OP_OLD_FRAMETYPE", Item1->FrameType); state->set("PATH_OP_OLD_OLDB2", Item1->OldB2); state->set("PATH_OP_OLD_OLDH2", Item1->OldH2); state->set("PATH_OP_NEW_FRAME", false); state->set("PATH_OP_NEW_CLIPEDITED", true); state->set("PATH_OP_NEW_FRAMETYPE", 3); } //>>#9046 Item1->PoLine = points; Item1->Frame = false; Item1->ClipEdited = true; Item1->FrameType = 3; currDoc->AdjustItemSize(Item1); Item1->OldB2 = Item1->width(); Item1->OldH2 = Item1->height(); Item1->updateClip(); Item1->ContourLine = Item1->PoLine.copy(); //<<#9046 if (UndoManager::undoEnabled()) { state->set("PATH_OP_NEW_OLDB2", Item1->OldB2); state->set("PATH_OP_NEW_OLDH2", Item1->OldH2); state->setItem(QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> >(QPair<FPointArray, FPointArray>(oldPOLine, oldContourLine), QPair<FPointArray, FPointArray>(Item1->PoLine, Item1->ContourLine))); undoManager->action(Item1, state); } //>>#9046 } path = QPainterPath(); path = dia->result1; if (!path.isEmpty()) { points.fromQPainterPath(path); //<<#9046 FPointArray oldPOLine=Item2->PoLine; FPointArray oldContourLine=Item2->ContourLine; ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >* state = NULL; if (UndoManager::undoEnabled()) { state = new ScItemState<QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> > >(Um::PathOperation); state->set("PATH_OPERATION", "path_operation"); state->set("PATH_OP_OLD_FRAME", Item2->Frame); state->set("PATH_OP_OLD_CLIPEDITED", Item2->ClipEdited); state->set("PATH_OP_OLD_FRAMETYPE", Item2->FrameType); state->set("PATH_OP_OLD_OLDB2", Item2->OldB2); state->set("PATH_OP_OLD_OLDH2", Item2->OldH2); state->set("PATH_OP_NEW_FRAME", false); state->set("PATH_OP_NEW_CLIPEDITED", true); state->set("PATH_OP_NEW_FRAMETYPE", 3); } //>>#9046 Item2->setXYPos(i1x, i1y); Item2->setRotation(0.0); Item2->PoLine = points; Item2->Frame = false; Item2->ClipEdited = true; Item2->FrameType = 3; currDoc->AdjustItemSize(Item2); Item2->OldB2 = Item2->width(); Item2->OldH2 = Item2->height(); Item2->updateClip(); Item2->ContourLine = Item2->PoLine.copy(); //<<#9046 if (UndoManager::undoEnabled()) { state->set("PATH_OP_NEW_OLDB2", Item2->OldB2); state->set("PATH_OP_NEW_OLDH2", Item2->OldH2); state->setItem(QPair<QPair<FPointArray, FPointArray>, QPair<FPointArray, FPointArray> >(QPair<FPointArray, FPointArray>(oldPOLine, oldContourLine), QPair<FPointArray, FPointArray>(Item2->PoLine, Item2->ContourLine))); undoManager->action(Item2, state); } //>>#9046 } path = QPainterPath(); path = dia->result2; if (!path.isEmpty()) { if (dia->targetColor == 0) { newItem = new PageItem_Polygon(*Item1); newItem->setXYPos(i1x, i1y); } else { newItem = new PageItem_Polygon(*Item2); newItem->setXYPos(i1x, i1y); newItem->setRotation(0.0); } currDoc->Items->append(newItem); newItem->setSelected(false); points.fromQPainterPath(path); newItem->PoLine = points; newItem->Frame = false; newItem->ClipEdited = true; newItem->FrameType = 3; currDoc->AdjustItemSize(newItem); newItem->OldB2 = newItem->width(); newItem->OldH2 = newItem->height(); newItem->updateClip(); newItem->ContourLine = newItem->PoLine.copy(); if (dia->targetColor == 2) { QString fill = dia->getOtherFillColor(); if (fill == CommonStrings::tr_NoneColor) fill = CommonStrings::None; newItem->setFillColor(fill); QString stroke = dia->getOtherLineColor(); if (stroke == CommonStrings::tr_NoneColor) stroke = CommonStrings::None; newItem->setLineColor(stroke); } } currDoc->m_Selection->clear(); currDoc->view()->Deselect(true); } currDoc->changed(); currDoc->view()->DrawNew(); } delete dia; //<<#9046 if (activeTransaction) { activeTransaction->commit(); delete activeTransaction; activeTransaction = NULL; } //>>#9046 return true; }
void GuiRiverEditorCtrl::on3DMouseDown(const Gui3DMouseEvent & event) { mGizmo->on3DMouseDown( event ); if ( !isFirstResponder() ) setFirstResponder(); // Get the raycast collision position Point3F tPos; if ( !getStaticPos( event, tPos ) ) return; // Construct a LineSegment from the camera position to 1000 meters away in // the direction clicked. // If that segment hits the terrain, truncate the ray to only be that length. // We will use a LineSegment/Sphere intersection test to determine if a RiverNode // was clicked. Point3F startPnt = event.pos; Point3F endPnt = event.pos + event.vec * 1000.0f; RayInfo ri; if ( gServerContainer.castRay(startPnt, endPnt, StaticObjectType, &ri) ) endPnt = ri.point; River *riverPtr = NULL; River *clickedRiverPtr = NULL; // Did we click on a river? check current selection first U32 insertNodeIdx = -1; Point3F collisionPnt; if ( mSelRiver != NULL && mSelRiver->collideRay( event.pos, event.vec, &insertNodeIdx, &collisionPnt ) ) { clickedRiverPtr = mSelRiver; } else { for ( SimSetIterator iter(mRiverSet); *iter; ++iter ) { riverPtr = static_cast<River*>( *iter ); if ( riverPtr->collideRay( event.pos, event.vec, &insertNodeIdx, &collisionPnt ) ) { clickedRiverPtr = riverPtr; break; } } } // Did we click on a riverNode? bool nodeClicked = false; S32 clickedNodeIdx = -1; F32 clickedNodeDist = mNodeSphereRadius; // If we clicked on the currently selected river, only scan its nodes if ( mSelRiver != NULL && clickedRiverPtr == mSelRiver ) { for ( U32 i = 0; i < mSelRiver->mNodes.size(); i++ ) { const Point3F &nodePos = mSelRiver->mNodes[i].point; Point3F screenPos; project( nodePos, &screenPos ); F32 dist = ( event.mousePoint - Point2I(screenPos.x, screenPos.y) ).len(); if ( dist < clickedNodeDist ) { clickedNodeDist = dist; clickedNodeIdx = i; nodeClicked = true; } } } else { for ( SimSetIterator iter(mRiverSet); *iter; ++iter ) { riverPtr = static_cast<River*>( *iter ); for ( U32 i = 0; i < riverPtr->mNodes.size(); i++ ) { const Point3F &nodePos = riverPtr->mNodes[i].point; Point3F screenPos; project( nodePos, &screenPos ); F32 dist = ( event.mousePoint - Point2I(screenPos.x, screenPos.y) ).len(); if ( dist < clickedNodeDist ) { // we found a hit! clickedNodeDist = dist; clickedNodeIdx = i; nodeClicked = true; clickedRiverPtr = riverPtr; } } } } // shortcuts bool dblClick = ( event.mouseClickCount > 1 ); if( dblClick ) { if( mMode == mSelectRiverMode ) { setMode( mAddRiverMode, true ); return; } if( mMode == mAddNodeMode ) { // Delete the node attached to the cursor. deleteSelectedNode(); mMode = mAddRiverMode; return; } } //this check is here in order to bounce back from deleting a whole road with ctrl+z //this check places the editor back into addrivermode if ( mMode == mAddNodeMode ) { if ( !mSelRiver ) mMode = mAddRiverMode; } if ( mMode == mSelectRiverMode ) { // Did not click on a River or a node. if ( !clickedRiverPtr ) { setSelectedRiver( NULL ); setSelectedNode( -1 ); return; } // Clicked on a River that wasn't the currently selected River. if ( clickedRiverPtr != mSelRiver ) { setSelectedRiver( clickedRiverPtr ); setSelectedNode( clickedNodeIdx ); return; } // Clicked on a node in the currently selected River that wasn't // the currently selected node. if ( nodeClicked ) { setSelectedNode( clickedNodeIdx ); return; } } else if ( mMode == mAddRiverMode ) { if ( nodeClicked ) { // A double-click on a node in Normal mode means set AddNode mode. if ( clickedNodeIdx == 0 ) { setSelectedRiver( clickedRiverPtr ); setSelectedNode( clickedNodeIdx ); mAddNodeIdx = clickedNodeIdx; mMode = mAddNodeMode; mSelNode = mSelRiver->insertNode( tPos, mDefaultWidth, mDefaultDepth, mDefaultNormal, mAddNodeIdx ); mIsDirty = true; return; } else if ( clickedNodeIdx == clickedRiverPtr->mNodes.size() - 1 ) { setSelectedRiver( clickedRiverPtr ); setSelectedNode( clickedNodeIdx ); mAddNodeIdx = U32_MAX; mMode = mAddNodeMode; mSelNode = mSelRiver->addNode( tPos, mDefaultWidth, mDefaultDepth, mDefaultNormal); mIsDirty = true; setSelectedNode( mSelNode ); return; } } if ( !isMethod( "createRiver" ) ) { Con::errorf( "GuiRiverEditorCtrl::on3DMouseDown - createRiver method does not exist." ); return; } const char *res = Con::executef( this, "createRiver" ); River *newRiver; if ( !Sim::findObject( res, newRiver ) ) { Con::errorf( "GuiRiverEditorCtrl::on3DMouseDown - createRiver method did not return a river object." ); return; } // Add to MissionGroup SimGroup *missionGroup; if ( !Sim::findObject( "MissionGroup", missionGroup ) ) Con::errorf( "GuiRiverEditorCtrl - could not find MissionGroup to add new River" ); else missionGroup->addObject( newRiver ); Point3F pos( endPnt ); pos.z += mDefaultDepth * 0.5f; newRiver->insertNode( pos, mDefaultWidth, mDefaultDepth, mDefaultNormal, 0 ); U32 newNode = newRiver->insertNode( pos, mDefaultWidth, mDefaultDepth, mDefaultNormal, 1 ); // Always add to the end of the road, the first node is the start. mAddNodeIdx = U32_MAX; setSelectedRiver( newRiver ); setSelectedNode( newNode ); mMode = mAddNodeMode; // Disable the hover node while in addNodeMode, we // don't want some random node enlarged. mHoverNode = -1; // Grab the mission editor undo manager. UndoManager *undoMan = NULL; if ( !Sim::findObject( "EUndoManager", undoMan ) ) { Con::errorf( "GuiMeshRoadEditorCtrl::on3DMouseDown() - EUndoManager not found!" ); return; } // Create the UndoAction. MECreateUndoAction *action = new MECreateUndoAction("Create MeshRoad"); action->addObject( newRiver ); // Submit it. undoMan->addAction( action ); return; } else if ( mMode == mAddNodeMode ) { // Oops the road got deleted, maybe from an undo action? // Back to NormalMode. if ( mSelRiver ) { // A double-click on a node in Normal mode means set AddNode mode. if ( clickedNodeIdx == 0 ) { submitUndo( "Add Node" ); mAddNodeIdx = clickedNodeIdx; mMode = mAddNodeMode; mSelNode = mSelRiver->insertNode( tPos, mDefaultWidth, mDefaultDepth, mDefaultNormal, mAddNodeIdx ); mIsDirty = true; setSelectedNode( mSelNode ); return; } else { if( clickedRiverPtr && clickedNodeIdx == clickedRiverPtr->mNodes.size() - 1 ) { submitUndo( "Add Node" ); mAddNodeIdx = U32_MAX; mMode = mAddNodeMode; U32 newNode = mSelRiver->addNode( tPos, mDefaultWidth, mDefaultDepth, mDefaultNormal); mIsDirty = true; setSelectedNode( newNode ); return; } else { submitUndo( "Insert Node" ); // A single-click on empty space while in // AddNode mode means insert / add a node. //submitUndo( "Add Node" ); //F32 width = mSelRiver->getNodeWidth( mSelNode ); U32 newNode = mSelRiver->insertNode( tPos, mDefaultWidth, mDefaultDepth, mDefaultNormal, mAddNodeIdx); mIsDirty = true; setSelectedNode( newNode ); return; } } } } else if ( mMode == mInsertPointMode && mSelRiver != NULL ) { if ( clickedRiverPtr == mSelRiver ) { // NOTE: I guess we have to determine the if the clicked ray intersects a road but not a specific node... // in order to handle inserting nodes in the same way as for DecalRoad U32 prevNodeIdx = insertNodeIdx; U32 nextNodeIdx = ( prevNodeIdx + 1 > mSelRiver->mNodes.size() - 1 ) ? prevNodeIdx : prevNodeIdx + 1; const RiverNode &prevNode = mSelRiver->mNodes[prevNodeIdx]; const RiverNode &nextNode = mSelRiver->mNodes[nextNodeIdx]; F32 width = ( prevNode.width + nextNode.width ) * 0.5f; F32 depth = ( prevNode.depth + nextNode.depth ) * 0.5f; Point3F normal = ( prevNode.normal + nextNode.normal ) * 0.5f; normal.normalize(); submitUndo( "Insert Node" ); U32 newNode = mSelRiver->insertNode( collisionPnt, width, depth, normal, insertNodeIdx + 1 ); mIsDirty = true; setSelectedNode( newNode ); return; } } else if ( mMode == mRemovePointMode && mSelRiver != NULL ) { if ( nodeClicked && clickedRiverPtr == mSelRiver ) { setSelectedNode( clickedNodeIdx ); deleteSelectedNode(); return; } } else if ( mMode == mMovePointMode ) { if ( nodeClicked && clickedRiverPtr == mSelRiver ) { setSelectedNode( clickedNodeIdx ); return; } } else if ( mMode == mScalePointMode ) { if ( nodeClicked && clickedRiverPtr == mSelRiver ) { setSelectedNode( clickedNodeIdx ); return; } } else if ( mMode == mRotatePointMode ) { if ( nodeClicked && clickedRiverPtr == mSelRiver ) { setSelectedNode( clickedNodeIdx ); return; } } }