The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
4.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-9 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. #include "../../../core/juce_StandardHeader.h"
  19. BEGIN_JUCE_NAMESPACE
  20. #include "juce_KeyboardFocusTraverser.h"
  21. #include "../juce_Component.h"
  22. //==============================================================================
  23. KeyboardFocusTraverser::KeyboardFocusTraverser()
  24. {
  25. }
  26. KeyboardFocusTraverser::~KeyboardFocusTraverser()
  27. {
  28. }
  29. //==============================================================================
  30. namespace KeyboardFocusHelpers
  31. {
  32. // This will sort a set of components, so that they are ordered in terms of
  33. // left-to-right and then top-to-bottom.
  34. class ScreenPositionComparator
  35. {
  36. public:
  37. ScreenPositionComparator() {}
  38. static int compareElements (const Component* const first, const Component* const second) throw()
  39. {
  40. int explicitOrder1 = first->getExplicitFocusOrder();
  41. if (explicitOrder1 <= 0)
  42. explicitOrder1 = std::numeric_limits<int>::max() / 2;
  43. int explicitOrder2 = second->getExplicitFocusOrder();
  44. if (explicitOrder2 <= 0)
  45. explicitOrder2 = std::numeric_limits<int>::max() / 2;
  46. if (explicitOrder1 != explicitOrder2)
  47. return explicitOrder1 - explicitOrder2;
  48. const int diff = first->getY() - second->getY();
  49. return (diff == 0) ? first->getX() - second->getX()
  50. : diff;
  51. }
  52. };
  53. static void findAllFocusableComponents (Component* const parent, Array <Component*>& comps)
  54. {
  55. if (parent->getNumChildComponents() > 0)
  56. {
  57. Array <Component*> localComps;
  58. ScreenPositionComparator comparator;
  59. int i;
  60. for (i = parent->getNumChildComponents(); --i >= 0;)
  61. {
  62. Component* const c = parent->getChildComponent (i);
  63. if (c->isVisible() && c->isEnabled())
  64. localComps.addSorted (comparator, c);
  65. }
  66. for (i = 0; i < localComps.size(); ++i)
  67. {
  68. Component* const c = localComps.getUnchecked (i);
  69. if (c->getWantsKeyboardFocus())
  70. comps.add (c);
  71. if (! c->isFocusContainer())
  72. findAllFocusableComponents (c, comps);
  73. }
  74. }
  75. }
  76. }
  77. static Component* getIncrementedComponent (Component* const current, const int delta) throw()
  78. {
  79. Component* focusContainer = current->getParentComponent();
  80. if (focusContainer != 0)
  81. {
  82. while (focusContainer->getParentComponent() != 0 && ! focusContainer->isFocusContainer())
  83. focusContainer = focusContainer->getParentComponent();
  84. if (focusContainer != 0)
  85. {
  86. Array <Component*> comps;
  87. KeyboardFocusHelpers::findAllFocusableComponents (focusContainer, comps);
  88. if (comps.size() > 0)
  89. {
  90. const int index = comps.indexOf (current);
  91. return comps [(index + comps.size() + delta) % comps.size()];
  92. }
  93. }
  94. }
  95. return 0;
  96. }
  97. Component* KeyboardFocusTraverser::getNextComponent (Component* current)
  98. {
  99. return getIncrementedComponent (current, 1);
  100. }
  101. Component* KeyboardFocusTraverser::getPreviousComponent (Component* current)
  102. {
  103. return getIncrementedComponent (current, -1);
  104. }
  105. Component* KeyboardFocusTraverser::getDefaultComponent (Component* parentComponent)
  106. {
  107. Array <Component*> comps;
  108. if (parentComponent != 0)
  109. KeyboardFocusHelpers::findAllFocusableComponents (parentComponent, comps);
  110. return comps.getFirst();
  111. }
  112. END_JUCE_NAMESPACE