diff --git a/Core/Code/Controllers/mitkFocusManager.cpp b/Core/Code/Controllers/mitkFocusManager.cpp index c4b43a551c..decc262252 100755 --- a/Core/Code/Controllers/mitkFocusManager.cpp +++ b/Core/Code/Controllers/mitkFocusManager.cpp @@ -1,145 +1,160 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkFocusManager.h" mitk::FocusManager::FocusManager() { m_Loop = true;//default m_FocusList.clear(); m_FocElement = NULL; } mitk::FocusManager::~FocusManager() { } bool mitk::FocusManager::AddElement(FocusElement* element) { // Try find mitk::FocusManager::FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),element); if (position != m_FocusList.end()) return false; m_FocusList.push_back(element); if (m_FocElement.GetPointer() == NULL) m_FocElement = element; return true; } bool mitk::FocusManager::RemoveElement(FocusElement* element) { - // Try find - mitk::FocusManager::FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),element); - if (position == m_FocusList.end()) - return false; - position = m_FocusList.erase(position); - // first delete the one on the position, and store the one afterewards into position - if ( m_FocusList.size() == 0 ) + if (element == m_FocElement) { - // no more FocusElements available - m_FocElement = NULL; + this->GoToNext(); } - else if ( position == m_FocusList.end() ) + + // Try to find + mitk::FocusManager::FocusListIterator position = std::find(m_FocusList.begin(), m_FocusList.end(), element); + if (position == m_FocusList.end()) { - // deleted was the last in row, then take the one before - m_FocElement = m_FocusList.back(); + return false; } - else + + m_FocusList.erase(position); + if (m_FocusList.empty()) { - // m_FocElement is equal to the next one in row - m_FocElement = *position; + m_FocElement = NULL; } + return true; } mitk::FocusManager::FocusElement* mitk::FocusManager::GetFocused() const { return m_FocElement.GetPointer(); } bool mitk::FocusManager::SetFocused(FocusElement* element) { if (m_FocElement == element) return true; FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),element); if (position == m_FocusList.end())//not found return false; m_FocElement = *position; ((const itk::Object*)this)->InvokeEvent(FocusEvent()); return true; } bool mitk::FocusManager::IsLast() { return (m_FocElement == m_FocusList.back()); } bool mitk::FocusManager::IsFirst() { return (m_FocElement == m_FocusList.front()); } const mitk::FocusManager::FocusElement* mitk::FocusManager::GetFirst() const { return (m_FocusList.front()).GetPointer(); } const mitk::FocusManager::FocusElement* mitk::FocusManager::GetLast() const { return (m_FocusList.back()).GetPointer(); } bool mitk::FocusManager::GoToNext() { + if (m_FocusList.empty()) + { + return false; + } + //find the m_FocElement - FocusListIterator position = std::find(m_FocusList.begin(),m_FocusList.end(),m_FocElement); - if (position == m_FocusList.end())//not found + FocusListIterator position = std::find(m_FocusList.begin(), m_FocusList.end(), m_FocElement); + if (position == m_FocusList.end()) + { return false; - else if (*position == m_FocusList.back())//last in row + } + + if (m_FocusList.size() == 1) + { + return true; + } + + FocusListIterator nextPosition = position + 1; + while(nextPosition != position) { - if (m_Loop) + if (nextPosition == m_FocusList.end()) { - m_FocElement = *(m_FocusList.begin()); - return true; + if (!m_Loop) + { + return false; + } + nextPosition = m_FocusList.begin(); } - else + + FocusElement* focusElement = *nextPosition; + if (focusElement->GetSizeX() > 0 && focusElement->GetSizeY() > 0) { - return false;//last in row and loop == false, so GoToNext == false + m_FocElement = focusElement; + return true; } + ++nextPosition; } - else //not last in row - { - m_FocElement = *(++position);//increase position and set m_FocElement - return true; - } + + m_FocElement = NULL; return false; } //##Documentation //## returns an iterator, that points to the //## beginning of the list mitk::FocusManager::FocusListIterator mitk::FocusManager::GetIter() { return m_FocusList.begin(); } void mitk::FocusManager::SetLoop(bool loop) { m_Loop = loop; } diff --git a/Core/Code/Controllers/mitkFocusManager.h b/Core/Code/Controllers/mitkFocusManager.h index 74ef59d3f6..cb5f13ad46 100755 --- a/Core/Code/Controllers/mitkFocusManager.h +++ b/Core/Code/Controllers/mitkFocusManager.h @@ -1,150 +1,149 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKFOCUSMANAGER_H_HEADER_INCLUDED_C135A197 #define MITKFOCUSMANAGER_H_HEADER_INCLUDED_C135A197 #include #include "mitkBaseRenderer.h" #include #pragma GCC visibility push(default) #include #pragma GCC visibility pop namespace mitk { //##Documentation //## @brief manages a list of BaseRenderer. //## //## A focuspointer can be set and read. //## GoToNext can be used to switch through the list. //## if the switch m_Loop is set to true, GetNext loops through the list; after //## the last it goes to the first. //## if it is not set, it returnes NULL if it steps behind the last Widget. //## @ingroup Interaction class MITK_CORE_EXPORT FocusManager : public itk::Object { public: mitkClassMacro(FocusManager, itk::Object); itkFactorylessNewMacro(Self) itkCloneMacro(Self) //##Documentation //##@brief Element, that can be focused and held here. //## - //## has to be an itk-Objekct in order to use itk-Smartpointer! + //## has to be an itk-Object in order to use itk-Smartpointer! typedef mitk::BaseRenderer FocusElement; typedef itk::WeakPointer FocusElementWeakPointer; typedef std::vector FocusElementList; typedef std::vector::iterator FocusListIterator; //##Documentation //## Destructor ~FocusManager(); //##Documentation //## Adds the widget into the set of managed Widgets after the focused //## widget and sets the focus to the added one if the list was empty before bool AddElement(FocusElement* element); //##Documentation //## removes the given widget from the list. //## true if found and removed, else false - //## afterwards the focused widget is the one behind the deleted - //## or if the deleted was the last, then the one before the deleted - //## that way you can delete sequentialy from the back on or from front to back + //## If the focus was on the removed widget then the next widget + //## will get the focus, as described in GoToNext(). bool RemoveElement(FocusElement* element); //##Documentation //## returns the focused Widget FocusElement* GetFocused() const; //##Documentation //## searches the given Widget in List; //## if found, sets the focus to this widget and returns true bool SetFocused(FocusElement* element); //##Documentation //## returns, if this focused widget points behind the end of the List bool IsLast(); //##Documentation //## returns true, if the focused widget is the first in the list bool IsFirst(); //##Documentation //## returns the first widget in list const FocusElement* GetFirst() const; //##Documentation //## returns the last widget in list const FocusElement* GetLast() const; //##Documentation //## sets the focus to the next in list //## loops the list, if switch loop is true //## returns true if successful, else false bool GoToNext(); //##Documentation //## returns an iterator, that points to the //## beginning of the list //## no changes are made to the current focused element FocusListIterator GetIter(); //##Documentation //## Sets the LoopMode. //## if set to true-> the one after the last is the first void SetLoop(bool loop); friend class GlobalInteraction; protected: //##Documentation //## Constructor FocusManager(); private: //##Documentation //## stores the Widgets FocusElementList m_FocusList; //##Documentation //## holds the focused Widget itk::WeakPointer m_FocElement; //##Documentation //## switch which sets the LoopMode. //## if true, then the next after the last one is the first bool m_Loop; }; #pragma GCC visibility push(default) //##Documentation //## @brief connect to this Event to get noticed when the focus changes itkEventMacro( FocusEvent , itk::AnyEvent ); #pragma GCC visibility pop } // namespace mitk #endif /* MITKFOCUSMANAGER_H_HEADER_INCLUDED_C135A197 */ diff --git a/Core/Code/Testing/mitkFocusManagerTest.cpp b/Core/Code/Testing/mitkFocusManagerTest.cpp index 1900f5446f..a2fe828de7 100644 --- a/Core/Code/Testing/mitkFocusManagerTest.cpp +++ b/Core/Code/Testing/mitkFocusManagerTest.cpp @@ -1,91 +1,94 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkFocusManager.h" #include "mitkTestingMacros.h" #include "mitkVtkPropRenderer.h" #include "mitkGlobalInteraction.h" int mitkFocusManagerTest(int /*argc*/, char* /*argv*/[]) { MITK_TEST_BEGIN("FocusManager"); // Global interaction must(!) be initialized if used mitk::GlobalInteraction::GetInstance()->Initialize("global"); mitk::RenderingManager::Pointer rm = mitk::RenderingManager::GetInstance(); //building up necessary objects vtkRenderWindow* renderWindow = vtkRenderWindow::New(); mitk::VtkPropRenderer::Pointer element1 = mitk::VtkPropRenderer::New( "renderer1", renderWindow, rm ); mitk::VtkPropRenderer::Pointer element2 = mitk::VtkPropRenderer::New( "renderer2", renderWindow, rm ); mitk::VtkPropRenderer::Pointer element3 = mitk::VtkPropRenderer::New( "renderer3", renderWindow, rm ); + element1->InitSize(100, 100); + element2->InitSize(100, 100); + element3->InitSize(100, 100); //the FocusManager itself mitk::FocusManager::Pointer focusManager = mitk::FocusManager::New(); //testing MITK_TEST_CONDITION_REQUIRED(focusManager.IsNotNull(), "Testing Instatiation"); MITK_TEST_CONDITION_REQUIRED(element1.IsNotNull(), "Testing Instatiation of an element"); MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element"); MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element is focused on"); MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing of an element"); MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == NULL, "Testing focused on an empty list"); MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element; Elements in list: 1"); MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element2), "Testing addition of a second element; Elements in list: 1 2"); MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1"); MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element3), "Testing addition of a third element; Elements in list: 1 2 3"); MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if the added element still is element 1"); MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element1), "Testing setting focused to element 1"); MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "focus on element 1"); MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element2), "Testing setting focused to element 2"); MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "focus on element 2"); MITK_TEST_CONDITION_REQUIRED(focusManager->SetFocused(element3), "Testing setting focused to element 3"); MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element3, "focus on element 3"); MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing first element; Elements in list: 2 3"); - MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is the one behind the deleted one: 2"); + MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element3, "Testing if focused element is still element 3"); MITK_TEST_CONDITION_REQUIRED(focusManager->AddElement(element1), "Testing addition of an element again; Elements in list: 2 3 1"); MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element3), "Testing removing element 3; Elements in list: 2 1"); MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element1, "Testing if focused element is the one behind the deleted one: 1"); MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element1), "Testing removing last element 1; Elements in list: 2 "); MITK_TEST_CONDITION_REQUIRED(focusManager->GetFocused() == element2, "Testing if focused element is 2"); MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing same element"); MITK_TEST_CONDITION_REQUIRED(focusManager->RemoveElement(element2), "Testing removing last element in list (2)"); MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element3), "Testing removing from empty list "); MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element2), "Testing removing from empty list with different object"); MITK_TEST_CONDITION_REQUIRED(!focusManager->RemoveElement(element1), "Testing removing from empty list with different object again"); focusManager = NULL; //TODO: test IsLast() IsFirst() GetFirst() GetLast() GoToNext() GetIter() SetLoop(bool loop) //Delete renderWindo correctly renderWindow->Delete(); MITK_TEST_END(); }