Commit c54d6d4e authored by Bob Obara's avatar Bob Obara

ENH: Hoving over associations now highlight in the 3D View

The qtAssociationWidget now can highlight geometry when the user hovers over the item in the list.
parent c19795a1
#New View Type - Associations
This view has the same syntax as an Attribute View but only allows the user to change the association information of the attribute resulting in taking up less screen Real Estate
#Changes to Attribute View
* added a new XML attribute "HideAssociations". If set to true the view will not display the association editing widget save screen Real Estate
* If there is only one type of attribute being created/modified then the type column is no longer displayed
......@@ -59,3 +60,6 @@ Added a new ReadOnly Option to Item Views. In the following example the item, a
#Changes to Displaying Items
* Extensible Group Items know display "Add Row" instead of "Add sub group" - this label can be changed using an ItemView with the XML attribute : ExtensibleLabel
* Added a FixedWidth Option for String, Double and Int ItemViews as also shown in the above example - **Note: setting the fixed width to 0 means there is no fixed width.**
#Other Changes
* Views showing associations will now highlight geometry when the user hovers over it
......@@ -9,19 +9,20 @@
//=========================================================================
#include "smtk/extension/paraview/appcomponents/pqSMTKAttributePanel.h"
#include "smtk/attribute/Attribute.h"
#include "smtk/attribute/Resource.h"
#include "smtk/extension/paraview/appcomponents/pqSMTKBehavior.h"
#include "smtk/extension/paraview/appcomponents/pqSMTKResource.h"
#include "smtk/extension/paraview/appcomponents/pqSMTKWrapper.h"
#include "smtk/view/View.h"
#include "smtk/attribute/Attribute.h"
#include "smtk/attribute/Resource.h"
#include "smtk/io/Logger.h"
#include "smtk/resource/Manager.h"
#include "smtk/resource/Resource.h"
#include "smtk/io/Logger.h"
#include "smtk/view/Selection.h"
#include "smtk/view/View.h"
#include "pqActiveObjects.h"
#include "pqApplicationCore.h"
......@@ -124,6 +125,10 @@ bool pqSMTKAttributePanel::displayResource(smtk::attribute::ResourcePtr rsrc)
m_attrUIMgr->setSelection(m_seln); // NB: m_seln may be null.
m_attrUIMgr->setSelectionBit(1); // ToDo: should be set by application
// Find or Create a value for highlight on hover
auto hoverBit = m_seln->findOrCreateLabeledValue("hovered");
m_attrUIMgr->setHoverBit(hoverBit);
smtk::view::ViewPtr view = rsrc ? rsrc->findTopLevelView() : nullptr;
if (view)
{
......
......@@ -16,6 +16,7 @@
#include "smtk/extension/qt/qtItem.h"
#include "smtk/extension/qt/qtSMTKUtilities.h"
#include "smtk/extension/qt/qtTableWidget.h"
#include "smtk/extension/qt/qtTypeDeclarations.h"
#include "smtk/extension/qt/qtUIManager.h"
#include "smtk/attribute/Attribute.h"
......@@ -32,6 +33,8 @@
#include "smtk/resource/Component.h"
#include "smtk/resource/Manager.h"
#include "smtk/view/Selection.h"
#include <QComboBox>
#include <QHBoxLayout>
#include <QKeyEvent>
......@@ -62,6 +65,8 @@ class qtAssociationWidgetInternals : public Ui::qtAttributeAssociation
public:
WeakAttributePtr currentAtt;
QPointer<qtBaseView> view;
QListWidgetItem* lastHighlightedItem;
QBrush normalBackground;
};
qtAssociationWidget::qtAssociationWidget(QWidget* _p, qtBaseView* bview)
......@@ -70,12 +75,34 @@ qtAssociationWidget::qtAssociationWidget(QWidget* _p, qtBaseView* bview)
this->Internals = new qtAssociationWidgetInternals;
this->Internals->setupUi(this);
this->Internals->view = bview;
this->initWidget();
std::ostringstream receiverSource;
receiverSource << "qtAssociationWidget_" << this;
m_selectionSourceName = receiverSource.str();
auto opManager = this->Internals->view->uiManager()->operationManager();
auto uiManager = this->Internals->view->uiManager();
if (uiManager == nullptr)
{
std::cerr << "qtAssociationWidget: Could not find UI Manager!\n";
return;
}
if (uiManager->highlightOnHover())
{
QObject::connect(this->Internals->CurrentList, SIGNAL(entered(const QModelIndex&)), this,
SLOT(hoverRow(const QModelIndex&)));
QObject::connect(this->Internals->AvailableList, SIGNAL(entered(const QModelIndex&)), this,
SLOT(hoverRow(const QModelIndex&)));
}
else
{
QObject::disconnect(this->Internals->CurrentList, SIGNAL(entered(const QModelIndex&)), this,
SLOT(hoverRow(const QModelIndex&)));
QObject::disconnect(this->Internals->AvailableList, SIGNAL(entered(const QModelIndex&)), this,
SLOT(hoverRow(const QModelIndex&)));
this->resetHover();
}
auto opManager = uiManager->operationManager();
if (opManager != nullptr)
{
m_operationObserverKey = opManager->observers().insert(
......@@ -100,6 +127,8 @@ qtAssociationWidget::qtAssociationWidget(QWidget* _p, qtBaseView* bview)
std::cerr << "qtAssociationWidget: Could not find Resource Manager!\n";
}
QObject::connect(this->Internals->view, SIGNAL(aboutToDestroy()), this, SLOT(removeObservers()));
this->Internals->lastHighlightedItem = nullptr;
}
qtAssociationWidget::~qtAssociationWidget()
......@@ -119,6 +148,8 @@ void qtAssociationWidget::initWidget()
// signals/slots
QObject::connect(this->Internals->MoveToRight, SIGNAL(clicked()), this, SLOT(onRemoveAssigned()));
QObject::connect(this->Internals->MoveToLeft, SIGNAL(clicked()), this, SLOT(onAddAvailable()));
this->Internals->CurrentList->setMouseTracking(true); // Needed to receive hover events.
this->Internals->AvailableList->setMouseTracking(true); // Needed to receive hover events.
}
bool qtAssociationWidget::hasSelectedItem()
......@@ -130,6 +161,17 @@ void qtAssociationWidget::showEntityAssociation(smtk::attribute::AttributePtr th
{
this->Internals->currentAtt = theAtt;
this->refreshAssociations();
// Lets store the normal backgound color of an item - we will
// need to use this when dealing with hovering
if (this->Internals->CurrentList->count())
{
this->Internals->normalBackground = this->Internals->CurrentList->item(0)->background();
}
else if (this->Internals->AvailableList->count())
{
this->Internals->normalBackground = this->Internals->AvailableList->item(0)->background();
}
}
void qtAssociationWidget::refreshAssociations()
......@@ -281,38 +323,13 @@ std::set<smtk::resource::PersistentObjectPtr> qtAssociationWidget::associatableO
smtk::resource::PersistentObjectPtr qtAssociationWidget::object(QListWidgetItem* item)
{
auto resManager = this->Internals->view->uiManager()->resourceManager();
smtk::resource::PersistentObjectPtr object;
if ((resManager == nullptr) || (item == nullptr))
if (item == nullptr)
{
smtk::resource::PersistentObjectPtr obj;
return obj;
}
QVariant var = item->data(Qt::UserRole);
smtk::common::UUID uid = qtSMTKUtilities::QVariantToUUID(var);
// Get the resource
smtk::resource::ResourcePtr res = resManager->get(uid);
if (res == nullptr)
{
std::cerr << "Could not find Item's Resource!\n";
return res;
}
// Now check to see if there is data associated with UserRole+1 which would mean we are
// dealing with a resource component
var = item->data(Qt::UserRole + 1);
if (!var.isValid())
{
return res;
}
uid = qtSMTKUtilities::QVariantToUUID(var);
auto comp = res->find(uid);
if (comp == nullptr)
{
std::cerr << "Could not find Item's Resource Component!\n";
}
return comp;
return item->data(Qt::UserRole).value<smtk::resource::PersistentObjectPtr>();
}
QList<QListWidgetItem*> qtAssociationWidget::getSelectedItems(QListWidget* theList) const
......@@ -356,19 +373,8 @@ QListWidgetItem* qtAssociationWidget::addObjectAssociationListItem(QListWidget*
QListWidgetItem* item =
new QListWidgetItem(QString::fromStdString(name), theList, smtk_USER_DATA_TYPE);
QVariant vdata;
//save the entity as a uuid strings
if (res)
{
vdata = qtSMTKUtilities::UUIDToQVariant(object->id());
item->setData(Qt::UserRole, vdata);
}
else
{
vdata = qtSMTKUtilities::UUIDToQVariant(comp->resource()->id());
item->setData(Qt::UserRole, vdata);
vdata = qtSMTKUtilities::UUIDToQVariant(comp->id());
item->setData(Qt::UserRole + 1, vdata);
}
vdata.setValue(object);
item->setData(Qt::UserRole, vdata);
theList->addItem(item);
if (sort)
{
......@@ -552,3 +558,91 @@ void qtAssociationWidget::handleResourceEvent(
this->refreshAssociations();
}
}
void qtAssociationWidget::leaveEvent(QEvent* evt)
{
this->resetHover();
// Now let the superclass do what it wants:
QWidget::leaveEvent(evt);
}
void qtAssociationWidget::hoverRow(const QModelIndex& idx)
{
auto uiManager = this->Internals->view->uiManager();
if (uiManager == nullptr)
{
return;
}
auto selection = uiManager->selection();
if (selection == nullptr)
{
return;
}
int row = idx.row();
// Lets create the hover background color;
// If there was a previously highlighted item and it is still using the
// hover color then reset its background;
if (this->Internals->lastHighlightedItem != nullptr)
{
this->Internals->lastHighlightedItem->setBackground(this->Internals->normalBackground);
}
// Discover what is currently hovered
auto obj = idx.data(Qt::UserRole).value<smtk::resource::PersistentObjectPtr>();
if (obj == nullptr)
{
return;
}
auto item = this->Internals->CurrentList->item(row);
if (item != nullptr)
{
auto iobj = item->data(Qt::UserRole).value<smtk::resource::PersistentObjectPtr>();
if (iobj != obj)
{
item = this->Internals->AvailableList->item(row);
}
}
else
{
item = this->Internals->AvailableList->item(row);
}
if (item)
{
item->setBackground(
QBrush(this->Internals->CurrentList->palette().highlight().color().lighter(125)));
this->Internals->lastHighlightedItem = item;
}
// Add new hover state
auto hoverMask = uiManager->hoverBit();
const auto& selnMap = selection->currentSelection();
auto cvit = selnMap.find(obj);
int sv = (cvit == selnMap.end() ? 0 : cvit->second) | hoverMask;
smtk::resource::PersistentObjectSet objs;
objs.insert(obj);
selection->modifySelection(
objs, m_selectionSourceName, sv, smtk::view::SelectionAction::UNFILTERED_REPLACE, true);
}
void qtAssociationWidget::resetHover()
{
auto uiManager = this->Internals->view->uiManager();
if (uiManager == nullptr)
{
return;
}
if (this->Internals->lastHighlightedItem != nullptr)
{
this->Internals->lastHighlightedItem->setBackground(this->Internals->normalBackground);
}
auto selection = uiManager->selection();
if (selection == nullptr)
{
return;
}
selection->resetSelectionBits(m_selectionSourceName, uiManager->hoverBit());
}
......@@ -49,6 +49,7 @@ public:
bool hasSelectedItem();
// when register the instance with qtSelectionManager, also add the memory address.
virtual std::string selectionSourceName() { return m_selectionSourceName; }
void leaveEvent(QEvent*) override;
public slots:
// Display the association information to a specific attribute
......@@ -63,6 +64,8 @@ protected slots:
virtual void onRemoveAssigned();
virtual void onAddAvailable();
virtual void removeObservers();
virtual void hoverRow(const QModelIndex& idx);
virtual void resetHover();
protected:
virtual void initWidget();
......
......@@ -139,6 +139,7 @@ void qtUIManager::commonConstructor()
m_minValueLabelLength = 50;
m_topLevelCategoriesSet = false;
m_categoryChecks = true;
m_highlightOnHover = true;
// default settings
this->advFont.setBold(true);
......@@ -147,6 +148,8 @@ void qtUIManager::commonConstructor()
this->InvalidValueColor.setRgbF(1.0, 0.5, 0.5);
m_currentAdvLevel = 0;
m_selectionBit = 0;
m_hoverBit = 0;
// Lets register some basic view constructors
this->registerViewConstructor("Analysis", qtAnalysisView::createViewWidget);
......
......@@ -190,6 +190,9 @@ public:
int selectionBit() const { return m_selectionBit; }
void setSelectionBit(int val) { m_selectionBit = val; }
int hoverBit() const { return m_hoverBit; }
void setHoverBit(int val) { m_hoverBit = val; }
// See if we are dealing with a subset of categories
bool topLevelCategoriesSet() const { return m_topLevelCategoriesSet; }
......@@ -197,6 +200,10 @@ public:
void setActiveTabInfo(const std::string& groupViewName, const std::string& activeTabName);
std::string activeTabInfo(const std::string& groupViewName) const;
bool highlightOnHover() const { return m_highlightOnHover; }
void setHighlightOnHover(bool val) { m_highlightOnHover = val; }
static qtItem* defaultItemConstructor(const AttributeItemInfo& info);
#ifdef _WIN32
......@@ -262,6 +269,11 @@ private:
smtk::view::SelectionPtr m_selection;
int m_selectionBit;
// For Hover-based information
bool m_highlightOnHover;
int m_hoverBit;
// indicates if the UI Manager should be filtering on categories at all
bool m_categoryChecks;
bool m_topLevelCategoriesSet;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment