From 08c78471c33ae6b1882510e1db74f658191ce619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Wed, 27 Jun 2018 13:15:20 +0200 Subject: [PATCH] AppFwk: Introduce SelectionChangedReceiver as a slimmer replacement for NotificationCenter --- .../cafPdmUiCore/CMakeLists.txt | 2 + .../cafSelectionChangedReceiver.cpp | 59 +++++++++++++++++++ .../cafSelectionChangedReceiver.h | 52 ++++++++++++++++ .../cafPdmUiCore/cafSelectionManager.cpp | 34 ++++++++--- .../cafPdmUiCore/cafSelectionManager.h | 18 ++++-- 5 files changed, 150 insertions(+), 15 deletions(-) create mode 100644 Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.cpp create mode 100644 Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.h diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt index 0c186d8a7a..9187c56a64 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/CMakeLists.txt @@ -53,6 +53,8 @@ set( PROJECT_FILES cafSelectionManager.cpp cafSelectionManager.h + cafSelectionChangedReceiver.h + cafSelectionChangedReceiver.cpp cafSelectionManagerTools.h ) diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.cpp new file mode 100644 index 0000000000..fa65b0effa --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.cpp @@ -0,0 +1,59 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## + +#include "cafSelectionChangedReceiver.h" +#include "cafSelectionManager.h" + +namespace caf +{ + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::SelectionChangedReceiver::SelectionChangedReceiver() +{ + SelectionManager::instance()->registerSelectionChangedReceiver(this); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::SelectionChangedReceiver::~SelectionChangedReceiver() +{ + SelectionManager::instance()->unregisterSelectionChangedReceiver(this); +} + +} \ No newline at end of file diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.h new file mode 100644 index 0000000000..3b7b181099 --- /dev/null +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionChangedReceiver.h @@ -0,0 +1,52 @@ +//################################################################################################## +// +// Custom Visualization Core library +// Copyright (C) Ceetron Solutions AS +// +// This library may be used under the terms of either the GNU General Public License or +// the GNU Lesser General Public License as follows: +// +// GNU General Public License Usage +// This library is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at <> +// for more details. +// +// GNU Lesser General Public License Usage +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU Lesser General Public License at <> +// for more details. +// +//################################################################################################## +#pragma once + +namespace caf +{ +class SelectionChangedReceiver +{ +public: + SelectionChangedReceiver(); + virtual ~SelectionChangedReceiver(); + +protected: + friend class SelectionManager; + /// Called whenever caf::SelectionManager's selection changes + virtual void onSelectionManagerSelectionChanged() = 0; +}; + +} diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp index 42c8195fad..d6e4c458a5 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.cpp @@ -79,8 +79,7 @@ void SelectionManager::selectedItems(std::vector& items, int role /* void SelectionManager::setSelectedItems(const std::vector& items, int role /*= SelectionManager::APPLICATION_GLOBAL*/) { std::vector< std::pair, PdmUiItem*> >& selection = m_selectionForRole[role]; - - selection.clear(); + std::vector< std::pair, PdmUiItem*> > newSelection; for (size_t i = 0; i < items.size(); i++) { @@ -89,19 +88,23 @@ void SelectionManager::setSelectedItems(const std::vector& items, in { PdmObjectHandle* obj = fieldHandle->fieldHandle()->ownerObject(); - selection.push_back(std::make_pair(obj, fieldHandle)); + newSelection.push_back(std::make_pair(obj, fieldHandle)); } else { PdmUiObjectHandle* obj = dynamic_cast(items[i]); if (obj) { - selection.push_back(std::make_pair(obj->objectHandle(), obj)); + newSelection.push_back(std::make_pair(obj->objectHandle(), obj)); } } } - notifySelectionChanged(); + if (newSelection != selection) + { + selection = newSelection; + notifySelectionChanged(); + } } //-------------------------------------------------------------------------------------------------- @@ -197,12 +200,17 @@ void SelectionManager::setSelectionFromReferences(const std::vector& re //-------------------------------------------------------------------------------------------------- void SelectionManager::clearAll() { + bool isChanged = false; for (size_t i = 0; i < m_selectionForRole.size(); i++) { - m_selectionForRole[i].clear(); + if ( m_selectionForRole[i].size()) + { + m_selectionForRole[i].clear(); + isChanged = true; + } } - notifySelectionChanged(); + if (isChanged) notifySelectionChanged(); } @@ -211,9 +219,12 @@ void SelectionManager::clearAll() //-------------------------------------------------------------------------------------------------- void SelectionManager::clear(int role) { - m_selectionForRole[role].clear(); + if ( m_selectionForRole[role].size() ) + { + m_selectionForRole[role].clear(); - notifySelectionChanged(); + notifySelectionChanged(); + } } //-------------------------------------------------------------------------------------------------- @@ -225,6 +236,11 @@ void SelectionManager::notifySelectionChanged() { m_notificationCenter->notifyObserversOfSelectionChange(); } + + for (auto receiver: m_selectionReceivers) + { + receiver->onSelectionManagerSelectionChanged(); + } } //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h index ca090c019e..9eba573021 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmUiCore/cafSelectionManager.h @@ -33,18 +33,16 @@ // for more details. // //################################################################################################## - - #pragma once -#include "cafPdmPointer.h" +#include "cafSelectionChangedReceiver.h" +#include "cafPdmPointer.h" #include "cafPdmField.h" -#include - #include - +#include +#include namespace caf { @@ -102,6 +100,8 @@ public: if (obj) typedObjects->push_back(obj); } } + + /// Returns the selected objects of the requested type if _all_ the selected objects are of the requested type template void objectsByTypeStrict(std::vector* typedObjects, int role = SelectionManager::APPLICATION_GLOBAL) @@ -124,12 +124,18 @@ private: SelectionManager(); void notifySelectionChanged(); + friend class SelectionChangedReceiver; + void registerSelectionChangedReceiver ( SelectionChangedReceiver* receiver) { m_selectionReceivers.insert(receiver);} + void unregisterSelectionChangedReceiver( SelectionChangedReceiver* receiver) { m_selectionReceivers.erase(receiver);} + private: std::vector < std::vector< std::pair, PdmUiItem*> > > m_selectionForRole; NotificationCenter* m_notificationCenter; PdmChildArrayFieldHandle* m_activeChildArrayFieldHandle; PdmPointer m_rootObject; + + std::set< SelectionChangedReceiver*> m_selectionReceivers; };