Exemple #1
0
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);
        }
Exemple #4
0
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;
   }

}