void dragTarget::mouseMoveEvent ( QMouseEvent *event ) //gestisce il trascinamento all'interno della lista stessa { if ( event -> buttons() == Qt::LeftButton && itemAt ( event -> pos() ) != NULL ) //se è iniziato un trascinamento con il tasto destro inizio a creare il mime { QTreeWidgetItem *current = itemAt(event -> pos()); showIndicator(visualItemRect(current).bottom()); if( this -> selectedItems().size() != 0 ) { int size = this -> selectedItems().size(); QList<QTreeWidgetItem*> selectedItems = this -> selectedItems(); for(int i = 0; i < size; i++) this -> setItemSelected(selectedItems[i], false); //deseleziona tutti gli altri elementi... evita un crash //NON SUPPORTIAMO ANCORA IL TRASCINAMENTO MULTIPLO } QDrag *drag = new QDrag ( this ); QMimeData * mimeData = new QMimeData; //QList<QTreeWidgetItem*> selectedItems = this -> selectedItems(); QTreeWidgetItem *toDrag = itemAt ( event -> pos() ); currentItem = toDrag; this -> setItemSelected ( toDrag, true ); drag -> setPixmap ( ( toDrag -> icon ( 0 ) ).pixmap ( 32,32 ) ); //recupero l'icona mimeData -> setImageData ( ( toDrag -> icon ( 0 ) ).pixmap ( 32,32 ) ); QString filePath = toDrag -> text ( 1 ) + toDrag -> text ( 0 ); //ricostruisco il percorso filePath.append ( "!*mimetosend:"+toDrag -> text ( 2 ) ); QByteArray mimeToSend = filePath.toAscii(); mimeData -> setData ( "aku/newarchive-fromHere",mimeToSend ); drag -> setMimeData ( mimeData ); drag -> exec ( Qt::MoveAction ); } else { hideIndicator(); event -> ignore(); return; } }
Indicator(const ObjectPtr &object, SceneManipulator *sceneManipulator) : mProxy(NULL) { assert(sceneManipulator); mUserAny = Ogre::Any(); mProxy = new ObjectProxy(object); // 根据光源位置来定节点位置 Ogre::Vector3 pos = VariantCast<Ogre::Vector3>(object->getProperty("position")); mIndicatorSceneNode = sceneManipulator->getIndicatorRootSceneNode()->createChildSceneNode(pos); Real radius = 5; int rings = 16; int segments = 16; Ogre::MeshPtr sphereMesh = createCommonSphere(radius, rings, segments); Ogre::MaterialPtr material = createPureColourMaterial( Ogre::ColourValue(1, 0, 0, 0.75) ); mIndicatorEntity = sceneManipulator->getSceneManager()->createEntity(mIndicatorSceneNode->getName(), sphereMesh->getName()); //david-<< //mIndicatorEntity->setNormaliseNormals(true); //david->> mIndicatorEntity->setMaterialName(material->getName()); setUserObject(mProxy); mIndicatorSceneNode->attachObject(mIndicatorEntity); // 选择时不考虑粒子系统的包围盒,用的是指示器的包围盒 ParticleSystemObject *particleSystemObject = static_cast<ParticleSystemObject *> (object.get()); Ogre::ParticleSystem *system = particleSystemObject->getParticleSystem(); if (system) system->setQueryFlags(0); // 根据光源类型来挂接模型 showIndicator(false); }
Indicator(const ObjectPtr &object, Ogre::SceneManager *sceneMgr, Fairy::SceneManipulator *sceneManipulator) : mProxy(NULL), mOldPos(Ogre::Vector3::ZERO) { assert(sceneMgr && sceneManipulator); mUserAny = Ogre::Any(); mProxy = new ObjectProxy(object); mSceneManipulator = sceneManipulator; mCurrentLightEntity = NULL; // 根据光源位置来定节点位置 Ogre::Vector3 pos = VariantCast<Ogre::Vector3>(object->getProperty("position")); mIndicatorSceneNode = sceneManipulator->getIndicatorRootSceneNode()->createChildSceneNode(pos); // mIndicatorSceneNode->scale(2.0,15.0,2.0); // 创建三个entity分别来代表三种光源的模型 mPointLightEntity = sceneMgr->createEntity(mIndicatorSceneNode->getName()+"point","pointLight.mesh"); mDirectionalLightEntity = sceneMgr->createEntity(mIndicatorSceneNode->getName()+"directional","directionalLight.mesh"); mDirectionalLightEntity->setQueryFlags(0); mSpotLightEntity = sceneMgr->createEntity(mIndicatorSceneNode->getName()+"spotlight","spotLight.mesh"); setUserObject(mProxy); // 根据光源类型来挂接模型 setIndicatorModel(mProxy->getObject()->getPropertyAsString("type")); // 根据光源方向来决定scenenode方向 Ogre::Vector3 &dir = VariantCast<Ogre::Vector3>(object->getProperty("direction")); setDirection(dir); showIndicator(false); }
void dragTarget::dragMoveEvent ( QDragMoveEvent *event ) { if ( event -> mouseButtons() == Qt::LeftButton ) { //eseguiamo lo scrollDown se ci troviamo alla fine della lista if(event -> pos().y() >viewport() -> height() - 50 && event -> pos().y() <viewport() -> height()) //se ci troviamo alla fine della lista iniziamo le operazioni di scroll automatico { tempScroll = itemAt(event -> pos()); connect(scrollDownTimer, SIGNAL(timeout()), this, SLOT(scrollDown())); scrollDownTimer -> start(100); } else { disconnect(scrollDownTimer, SIGNAL(timeout()), this, SLOT(scrollDown())); scrollDownTimer -> stop(); } //eseguiamo lo scrollUp se ci troviamo all'inizio della lista if(event -> pos().y() < viewport() -> y() + 20 && event -> pos().y() > 0) //se ci troviamo all'inizio della lista iniziamo le operazioni di scroll automatico { tempScroll = itemAt(event -> pos()); connect(scrollUpTimer, SIGNAL(timeout()), this, SLOT(scrollUp())); scrollUpTimer -> start(100); } else { disconnect(scrollUpTimer, SIGNAL(timeout()), this, SLOT(scrollUp())); scrollUpTimer -> stop(); } if(itemAt(event -> pos()) != NULL) { QTreeWidgetItem *current = itemAt(event -> pos() ); showIndicator(visualItemRect(current).bottom()); if(indicatorToRestore != NULL && itemAt(event -> pos()) != indicatorToRestore) { delete indicatorToRestore; indicatorToRestore = NULL; } } else { if(indicatorToRestore != NULL) delete indicatorToRestore; indicatorToRestore = new QTreeWidgetItem(this); scrollToItem(indicatorToRestore); showIndicator(visualItemRect(topLevelItem(topLevelItemCount()-1)).bottom()); } //------------------------------------------iniziano le operazioni di allocazione-----------------------------------------------------------------------------// QList<QTreeWidgetItem*> selectedItems = this -> selectedItems(); //mi serve per accertarmi che l'utente non voglia trascinare un file sul file stesso if ( selectedItems.size() == 0 ) //se non ci sono elementi selezionati { //*******************************************************************// if ( itemAt ( event -> pos() ) != NULL && itemAt ( event -> pos() ) -> text ( 2 ) == "inode/directory" ) //se voglio trascinare su un altro elemento che è una cartella, acconsento, TODO ma solo se la cartella non contiene già un elemento uguale { subLevel = true; padre = itemAt ( event -> pos() ); event -> acceptProposedAction(); } else { if ( itemAt ( event -> pos() ) != NULL && itemAt ( event -> pos() ) -> text ( 2 ) !="inode/directory" ) { if(itemAt( event -> pos() ) -> text(0) == "") { //possiamo trascinare sull'indicatore subLevel = false; event -> acceptProposedAction(); } else event -> ignore();//se voglio trascinare su un elemento che non è una cartella, nego } else //se voglio semplicemente trascinare un nuovo elemento acconsento { subLevel = false; event -> acceptProposedAction(); } } //*************************************************************// } //fine dell'if selectedItems.size() else //se ci sono elementi selezionati mi accerto di non trascinare su me stesso e di non trascinarmi in un mio figlio { if ( itemAt ( event -> pos() ) != NULL && itemAt ( event -> pos() ) -> text ( 2 ) == "inode/directory" && itemAt ( event -> pos() ) != selectedItems[0] ) //se voglio trascinare su un elemento che è una cartella e non è l'elemento stesso { QString nomeFile; //recupero il nome file dell'elemento per accertarmi di non trascinarmi in un mio figlio //QStringList formati = event -> mimeData() -> formats(); if(event -> mimeData()->hasFormat("aku/newarchive")) nomeFile = event -> mimeData()->data ( "aku/newarchive" ); else nomeFile = event -> mimeData()->data("aku/newarchive-fromHere"); QStringList path = nomeFile.split ( QDir().separator() ); int target = path[path.size()-1].indexOf ( "!*mimetosend:" ); path[path.size()-1].remove ( target, path[path.size()-1].length() ); QString temp = path[path.size()-1]; //nome del parent (directory) bool checkHasSameParent = hasSameParent ( itemAt ( event -> pos() ), temp ); //con questo evito di trascinare un parent in un suo figlio if ( checkHasSameParent == false ) { subLevel = true; padre = itemAt ( event -> pos() ); event -> acceptProposedAction(); } else { event -> ignore(); ///return; } /****************************************************************************************/ // devo controllare di non trascinare su uno stesso parent.. perchè è inutile e rende instabile tutto :-D bool allowAllocation = true; for ( int i = 0; i < itemAt ( event -> pos() ) -> childCount(); i++ ) //se l'elemento di destinazione ha tra i suoi figli uno con lo stesso nome di quello che sto trascinando allora nego il trascinamento { if ( itemAt ( event -> pos() ) -> child ( i )->text ( 0 ) == temp ) allowAllocation = false; //se non ha un child con lo stesso nome permettiamo l'allocazione } if ( allowAllocation == true ) { subLevel = true; padre = itemAt ( event -> pos() ); event -> acceptProposedAction(); } else { event -> ignore(); ///return; } /****************************************************************************************/ } else //altrimenti { if ( itemAt ( event -> pos() ) == NULL ) //se il cursore non si trova su nessun elemento vuol dire che posso allocare nella lista { subLevel = false; event -> acceptProposedAction(); } else { if(itemAt( event -> pos() ) -> text(0) == "") { //possiamo trascinare sull'indicatore subLevel = false; event -> acceptProposedAction(); } else { event -> ignore(); // altrimenti ignoro ///return; } } } } } else //se non è iniziato il trascinamento col tasto sinistro chiudo { event -> ignore(); return; } }