From f52e5973a9c5d2a9cb98d77e585eba71ac606c5b Mon Sep 17 00:00:00 2001 From: mzn Date: Tue, 1 Apr 2014 09:19:57 +0000 Subject: [PATCH] Allow drag and drop berween items; change z layers assigning algo. --- src/HYDROGUI/HYDROGUI_ListModel.cxx | 28 +-- src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx | 193 ++++++++++++++------ src/HYDROGUI/HYDROGUI_OCCDisplayer.h | 16 ++ src/HYDROGUI/HYDROGUI_OrderedListWidget.cxx | 4 +- src/HYDROGUI/HYDROGUI_OrderedListWidget.h | 2 +- 5 files changed, 171 insertions(+), 72 deletions(-) diff --git a/src/HYDROGUI/HYDROGUI_ListModel.cxx b/src/HYDROGUI/HYDROGUI_ListModel.cxx index bfda69d9..24e3fe8f 100644 --- a/src/HYDROGUI/HYDROGUI_ListModel.cxx +++ b/src/HYDROGUI/HYDROGUI_ListModel.cxx @@ -48,7 +48,7 @@ HYDROGUI_ListModel::HYDROGUI_ListModel( QObject* theParent ) // Define eye icon and empty icon myEmpty = QPixmap( 16, 16 ); - myEmpty.fill( Qt::white ); + myEmpty.fill( Qt::transparent ); if ( aResMgr ) { myEye = aResMgr->loadPixmap( "HYDRO", tr( "EYE_ICO" ) ); } else { @@ -171,8 +171,8 @@ bool HYDROGUI_ListModel::isObjectVisible( int theIndex ) const /** */ QVariant HYDROGUI_ListModel::headerData( int theSection, - Qt::Orientation theOrientation, - int theRole ) const + Qt::Orientation theOrientation, + int theRole ) const { if( theOrientation==Qt::Horizontal && theRole==Qt::DisplayRole ) { @@ -206,7 +206,7 @@ QMimeData* HYDROGUI_ListModel::mimeData( const QModelIndexList& theIndexes ) con QByteArray anEncodedData; QDataStream aStream( &anEncodedData, QIODevice::WriteOnly ); - QList anIdsList = getIds( theIndexes ); + QList anIdsList = getIds( theIndexes, true ); foreach( int anId, anIdsList ) aStream << anId; @@ -226,7 +226,7 @@ QStringList HYDROGUI_ListModel::mimeTypes() const /** */ bool HYDROGUI_ListModel::dropMimeData( const QMimeData* theData, Qt::DropAction theAction, - int theRow, int theColumn, const QModelIndex& theParent ) + int theRow, int theColumn, const QModelIndex& theParent ) { if( theAction == Qt::IgnoreAction) return true; @@ -237,7 +237,8 @@ bool HYDROGUI_ListModel::dropMimeData( const QMimeData* theData, Qt::DropAction if( theColumn > 0 ) return false; - int aDropItemId = theParent.row(); + // TODO: to disable drop between items use: int aDropItemId = theParent.row(); + int aDropItemId = theParent.isValid() ? theParent.row() : theRow; QByteArray anEncodedData = theData->data( OBJ_LIST_MIME_TYPE ); QDataStream aStream( &anEncodedData, QIODevice::ReadOnly ); @@ -248,7 +249,7 @@ bool HYDROGUI_ListModel::dropMimeData( const QMimeData* theData, Qt::DropAction aStream >> anId; anIdsList << anId; } - qSort( anIdsList ); // TODO should be moved? + move( anIdsList, DragAndDrop, false, aDropItemId ); //TODO set visibility? return true; } @@ -265,7 +266,8 @@ Qt::DropActions HYDROGUI_ListModel::supportedDropActions() const @param theIsToSort defines if the list of ids should be sorted in ascending order @return the list of ids */ -QList HYDROGUI_ListModel::getIds( const QModelIndexList& theIndexes, bool theIsToSort ) const +QList HYDROGUI_ListModel::getIds( const QModelIndexList& theIndexes, + bool theIsToSort ) const { QList anIds; foreach( const QModelIndex& anIndex, theIndexes ) { @@ -288,7 +290,7 @@ QList HYDROGUI_ListModel::getIds( const QModelIndexList& theIndexes, bool t @return true in case of success */ bool HYDROGUI_ListModel::move( const int theItem, const OpType theType, - bool theIsVisibleOnly, const int theDropItem ) + bool theIsVisibleOnly, const int theDropItem ) { bool aRes = false; if ( theItem < 0 || theItem >= myObjects.count() ) { @@ -362,7 +364,7 @@ bool HYDROGUI_ListModel::move( const int theItem, const OpType theType, @return true in case of success */ bool HYDROGUI_ListModel::move( const QList& theItems, const OpType theType, - bool theIsVisibleOnly, const int theDropItem ) + bool theIsVisibleOnly, const int theDropItem ) { bool aRes = true; @@ -437,11 +439,13 @@ bool HYDROGUI_ListModel::move( const QList& theItems, const OpType theType, @return true if drag and drop allowed */ bool HYDROGUI_ListModel::isDragAndDropAllowed( const QList& theItems, - const int theDropItem ) const + const int theDropItem ) const { bool isAllowed = false; - if ( theDropItem >= 0 && theDropItem < myObjects.count() && + if ( theDropItem >= 0 && + // TODO: to disable drop between items use: theDropItem < myObjects.count() + theDropItem <= myObjects.count() && !theItems.empty() && theItems.count() < myObjects.count() && !theItems.contains( theDropItem )) { isAllowed = true; diff --git a/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx b/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx index ee57bf97..5e7efdf3 100644 --- a/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx +++ b/src/HYDROGUI/HYDROGUI_OCCDisplayer.cxx @@ -154,100 +154,84 @@ void HYDROGUI_OCCDisplayer::Display( const HYDROData_SequenceOfObjects& theObjs, const bool theIsForced, const bool theDoFitAll ) { + // Get OCC viewer by id OCCViewer_Viewer* aViewer = module()->getOCCViewer( theViewerId ); if( !aViewer ) return; + // Get interactive context Handle(AIS_InteractiveContext) aCtx = aViewer->getAISContext(); if( aCtx.IsNull() ) return; - + // Get the document Handle(HYDROData_Document) aDoc = HYDROData_Document::Document( module()->getStudyId() ); if ( !aDoc ) return; - // Assign Z layer indexes + // Assign Z layer indexes to the objects aDoc->Show( theObjs ); - // TODO: to optimize // Sort objects by display order ( needed for Z layers assignment only ) - typedef QPair Object2ApplyZLayer; - QList anOrderedToDisplay; // list of (object, is_z_layer_applicable) - HYDROData_SequenceOfObjects anObjectsToDisplay = theObjs; - HYDROData_SequenceOfObjects anOrderedObjects = aDoc->GetObjectsLayerOrder(); - - HYDROData_SequenceOfObjects::Iterator anOrderedIter( anOrderedObjects ); - for ( ; anOrderedIter.More(); anOrderedIter.Next() ) { - QString anOrderedEntry = HYDROGUI_DataObject::dataObjectEntry( anOrderedIter.Value() ); + HYDROData_SequenceOfObjects anUnorderedToDisplay = theObjs; + HYDROData_SequenceOfObjects anOrderedToDisplay; + HYDROData_SequenceOfObjects anAllOrderedObjects = aDoc->GetObjectsLayerOrder(); + + HYDROData_SequenceOfObjects::Iterator anAllOrderedIter( anAllOrderedObjects ); + for ( ; anAllOrderedIter.More(); anAllOrderedIter.Next() ) { + QString anOrderedEntry = + HYDROGUI_DataObject::dataObjectEntry( anAllOrderedIter.Value() ); - HYDROData_SequenceOfObjects::Iterator aToDisplayIter( anObjectsToDisplay ); + HYDROData_SequenceOfObjects::Iterator aToDisplayIter( anUnorderedToDisplay ); for ( ; aToDisplayIter.More(); aToDisplayIter.Next() ) { Handle(HYDROData_Entity) anObjToDisplay = aToDisplayIter.Value(); QString anEntry = HYDROGUI_DataObject::dataObjectEntry( anObjToDisplay ); if ( anEntry == anOrderedEntry ) { - anObjectsToDisplay.Remove( aToDisplayIter ); - anOrderedToDisplay.prepend( Object2ApplyZLayer( anObjToDisplay, true ) ); + anOrderedToDisplay.Prepend( anObjToDisplay ); + anUnorderedToDisplay.Remove( aToDisplayIter ); break; } } } - // For the rest objects Z layer can't be applied - HYDROData_SequenceOfObjects::Iterator aRestObjsIter( anObjectsToDisplay ); - for ( ; aRestObjsIter.More(); aRestObjsIter.Next() ) { - anOrderedToDisplay.prepend( Object2ApplyZLayer( aRestObjsIter.Value(), false ) ); - } + + // Get 3d viewer + Handle(V3d_Viewer) aViewer3d = aViewer->getViewer3d(); // Get existing Z layers TColStd_SequenceOfInteger anExistingZLayers; - aViewer->getViewer3d()->GetAllZLayers( anExistingZLayers ); + aViewer3d->GetAllZLayers( anExistingZLayers ); int aNbLayers = anExistingZLayers.Length(); - // Display + // Display objects int aNextZLayerIndex = 2; // don't use the first default Z layer ( which index = 1 ) - foreach ( const Object2ApplyZLayer& aPair, anOrderedToDisplay ) { - Handle(HYDROData_Entity) anObj = aPair.first; - if ( anObj.IsNull() || anObj->IsRemoved() ) - continue; - - HYDROGUI_Shape* anObjShape = module()->getObjectShape( (size_t)aViewer, anObj ); - if ( !anObjShape || anObjShape->getIsToUpdate() || theIsForced ) - { - if ( !anObjShape ) - anObjShape = createShape( (size_t)aViewer, aCtx, anObj ); - - if ( anObjShape ) - anObjShape->update( false ); + // 1. Display the ordered objects: + HYDROData_SequenceOfObjects::Iterator anOrderedIter( anOrderedToDisplay ); + for ( ; anOrderedIter.More(); anOrderedIter.Next() ) { + Handle(HYDROData_Entity) anObj = anOrderedIter.Value(); + if ( Display( anObj, aViewer, theIsForced, aNextZLayerIndex, true ) ) { + aNextZLayerIndex++; } + } - if ( anObjShape ) - { - bool anIsVisible = module()->isObjectVisible( (size_t)aViewer, anObj ); - anObjShape->setVisible( anIsVisible, false ); - - bool isZLayerApplicable = aPair.second; - - // set Z layer if applicable - if ( isZLayerApplicable ) { - Standard_Integer aLayerId = -1; - if ( aNextZLayerIndex <= aNbLayers ) { - aLayerId = anExistingZLayers.Value( aNextZLayerIndex ); - } else { - Standard_Integer aNewId = -1; - if ( aViewer->getViewer3d()->AddZLayer( aNewId ) ) { - aLayerId = aNewId; - } - } - if ( aLayerId >= 0 ) { - aCtx->SetZLayer( anObjShape->getAISShape(), aLayerId ); - } - aNextZLayerIndex++; - } + // 2. Display the unordered objects: + bool isDisplayed = false; + HYDROData_SequenceOfObjects::Iterator anUnorderedIter( anUnorderedToDisplay ); + for ( ; anUnorderedIter.More(); anUnorderedIter.Next() ) { + Handle(HYDROData_Entity) anObj = anUnorderedIter.Value(); + if ( Display( anObj, aViewer, theIsForced, aNextZLayerIndex, false ) ) { + isDisplayed = true; } } + + // 3. Update the top Z layer index + if ( isDisplayed ) { + aNextZLayerIndex++; + } // Update Z layer of the active operation + aViewer3d->GetAllZLayers( anExistingZLayers ); + HYDROGUI_Module* aModule = module(); SUIT_Operation* anOp = aModule->activeOperation(); HYDROGUI_Operation* aHOp = anOp ? dynamic_cast( anOp ) : 0; @@ -278,7 +262,7 @@ void HYDROGUI_OCCDisplayer::Display( const HYDROData_SequenceOfObjects& theObjs, } } } - else if ( aCtx.IsNull() ) + else if ( !aCtx.IsNull() ) // TODO: determine if this code is necessary (added as a fix for issue# 359) { aCtx->UpdateSelected(); } @@ -315,3 +299,96 @@ QString HYDROGUI_OCCDisplayer::GetType() const { return OCCViewer_Viewer::Type(); } + +bool HYDROGUI_OCCDisplayer::Display( const Handle(HYDROData_Entity)& theObject, + const OCCViewer_Viewer* theViewer, + const bool theIsForced, + const int theZLayerIndex, + const bool theIsOrdered ) +{ + bool aRes = false; + + if ( theObject.IsNull() || theObject->IsRemoved() || !theViewer ) { + return aRes; + } + + // Get interactive context + Handle(AIS_InteractiveContext) aCtx = theViewer->getAISContext(); + if( aCtx.IsNull() ) { + return aRes; + } + + // Viewer id + size_t aViewerId = (size_t)theViewer; + + // Object shape + HYDROGUI_Shape* anObjShape = module()->getObjectShape( aViewerId, theObject ); + // create if needed + if ( !anObjShape ) { + anObjShape = createShape( aViewerId, aCtx, theObject ); + anObjShape->setIsToUpdate( true ); + } + + // Process the shape + if ( anObjShape ) { + // update if needed + if ( anObjShape->getIsToUpdate() || theIsForced ) { + anObjShape->update( false ); + } + + // Set visibility + bool anIsVisible = module()->isObjectVisible( aViewerId, theObject ); + anObjShape->setVisible( anIsVisible, false ); + + // Set Z layer + Handle(V3d_Viewer) aViewer3d = theViewer->getViewer3d(); + if ( !aViewer3d.IsNull() ) { + // Get existing layers + TColStd_SequenceOfInteger anExistingZLayers; + aViewer3d->GetAllZLayers( anExistingZLayers ); + int aNbLayers = anExistingZLayers.Length(); + + // Get or create the appropriate layer + Standard_Integer aLayerId = -1; + if ( theZLayerIndex <= aNbLayers ) { + aLayerId = anExistingZLayers.Value( theZLayerIndex ); + } else { + Standard_Integer aNewId = -1; + if ( aViewer3d->AddZLayer( aNewId ) ) { + aLayerId = aNewId; + } + } + + if ( aLayerId >= 0 ) { + // set Z layer + aCtx->SetZLayer( anObjShape->getAISShape(), aLayerId ); + + // set Z layer settings for the 3d viewer: + // current settings + Graphic3d_ZLayerSettings aSettings = aViewer3d->ZLayerSettings( aLayerId ); + // enable depth write + aSettings.EnableSetting( Graphic3d_ZLayerDepthWrite ); + // disable depth clear + aSettings.DisableSetting( Graphic3d_ZLayerDepthClear ); + if ( theIsOrdered ) { + // disable depth test + aSettings.DisableSetting( Graphic3d_ZLayerDepthTest ); + // disable depth offset + aSettings.DisableSetting( Graphic3d_ZLayerDepthOffset ); + } else { + // enable depth test + aSettings.EnableSetting( Graphic3d_ZLayerDepthTest ); + // set depth offset + aSettings.SetDepthOffsetPositive(); + } + + // set new settings + aViewer3d->SetZLayerSettings( aLayerId, aSettings ); + + aRes = true; + } + } + } + + return aRes; +} \ No newline at end of file diff --git a/src/HYDROGUI/HYDROGUI_OCCDisplayer.h b/src/HYDROGUI/HYDROGUI_OCCDisplayer.h index d3493654..f1cb0256 100644 --- a/src/HYDROGUI/HYDROGUI_OCCDisplayer.h +++ b/src/HYDROGUI/HYDROGUI_OCCDisplayer.h @@ -28,6 +28,7 @@ class HYDROGUI_Shape; class Handle(AIS_InteractiveContext); class OCCViewer_ViewManager; +class OCCViewer_Viewer; /** * \class HYDROGUI_OCCDisplayer @@ -120,6 +121,21 @@ private: HYDROGUI_Shape* createShape( const int theViewerId, const Handle(AIS_InteractiveContext)& theContext, const Handle(HYDROData_Entity)& theObject ); + + /** + * \brief Display the specified object. + * \param theObject the object to display + * \param theViewer the viewer for displaying + * \param theIsForced the flag used to update the object shape + * \param theZLayerIndex the Z layer index + * \param theIsOrdered the flag indicating if the Z layer ordering available for the object + * \return true in case of success + */ + bool Display( const Handle(HYDROData_Entity)& theObject, + const OCCViewer_Viewer* theViewer, + const bool theIsForced, + const int theZLayerIndex, + const bool theIsOrdered ); }; #endif diff --git a/src/HYDROGUI/HYDROGUI_OrderedListWidget.cxx b/src/HYDROGUI/HYDROGUI_OrderedListWidget.cxx index 414186ec..671102d0 100644 --- a/src/HYDROGUI/HYDROGUI_OrderedListWidget.cxx +++ b/src/HYDROGUI/HYDROGUI_OrderedListWidget.cxx @@ -48,12 +48,14 @@ HYDROGUI_OrderedListWidget::HYDROGUI_OrderedListWidget( QWidget* theParent ) // List view myList = new QListView( this ); myList->setSelectionMode( QAbstractItemView::ExtendedSelection ); + // enable drag and drop myList->setDragEnabled( true ); myList->setAcceptDrops( true ); - myList->viewport()->setAcceptDrops( true ); + // configure drag and drop myList->setDropIndicatorShown( true ); myList->setDragDropMode( QAbstractItemView::InternalMove ); + // Set the custom model HYDROGUI_ListModel* aModel = new HYDROGUI_ListModel(); QSortFilterProxyModel* aFilteredModel = new QSortFilterProxyModel(); aFilteredModel->setSourceModel( aModel ); diff --git a/src/HYDROGUI/HYDROGUI_OrderedListWidget.h b/src/HYDROGUI/HYDROGUI_OrderedListWidget.h index 9664e98f..698c8533 100644 --- a/src/HYDROGUI/HYDROGUI_OrderedListWidget.h +++ b/src/HYDROGUI/HYDROGUI_OrderedListWidget.h @@ -69,7 +69,7 @@ private: QToolButton* myDown; ///< the move down button QToolButton* myBottom; ///< the move on bottom button - bool myIsHiddenObjectsShown; ///< the show hidden objects in the list indicator + bool myIsHiddenObjectsShown; ///< defines whether to include hidden objects in the list }; #endif -- 2.39.2