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.

147 lines
4.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 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. BEGIN_JUCE_NAMESPACE
  19. //==============================================================================
  20. KeyboardFocusTraverser::KeyboardFocusTraverser()
  21. {
  22. }
  23. KeyboardFocusTraverser::~KeyboardFocusTraverser()
  24. {
  25. }
  26. //==============================================================================
  27. namespace KeyboardFocusHelpers
  28. {
  29. // This will sort a set of components, so that they are ordered in terms of
  30. // left-to-right and then top-to-bottom.
  31. class ScreenPositionComparator
  32. {
  33. public:
  34. ScreenPositionComparator() {}
  35. static int compareElements (const Component* const first, const Component* const second)
  36. {
  37. int explicitOrder1 = first->getExplicitFocusOrder();
  38. if (explicitOrder1 <= 0)
  39. explicitOrder1 = std::numeric_limits<int>::max() / 2;
  40. int explicitOrder2 = second->getExplicitFocusOrder();
  41. if (explicitOrder2 <= 0)
  42. explicitOrder2 = std::numeric_limits<int>::max() / 2;
  43. if (explicitOrder1 != explicitOrder2)
  44. return explicitOrder1 - explicitOrder2;
  45. const int diff = first->getY() - second->getY();
  46. return (diff == 0) ? first->getX() - second->getX()
  47. : diff;
  48. }
  49. };
  50. static void findAllFocusableComponents (Component* const parent, Array <Component*>& comps)
  51. {
  52. if (parent->getNumChildComponents() > 0)
  53. {
  54. Array <Component*> localComps;
  55. ScreenPositionComparator comparator;
  56. int i;
  57. for (i = parent->getNumChildComponents(); --i >= 0;)
  58. {
  59. Component* const c = parent->getChildComponent (i);
  60. if (c->isVisible() && c->isEnabled())
  61. localComps.addSorted (comparator, c);
  62. }
  63. for (i = 0; i < localComps.size(); ++i)
  64. {
  65. Component* const c = localComps.getUnchecked (i);
  66. if (c->getWantsKeyboardFocus())
  67. comps.add (c);
  68. if (! c->isFocusContainer())
  69. findAllFocusableComponents (c, comps);
  70. }
  71. }
  72. }
  73. }
  74. namespace KeyboardFocusHelpers
  75. {
  76. Component* getIncrementedComponent (Component* const current, const int delta)
  77. {
  78. Component* focusContainer = current->getParentComponent();
  79. if (focusContainer != nullptr)
  80. {
  81. while (focusContainer->getParentComponent() != nullptr && ! focusContainer->isFocusContainer())
  82. focusContainer = focusContainer->getParentComponent();
  83. if (focusContainer != nullptr)
  84. {
  85. Array <Component*> comps;
  86. KeyboardFocusHelpers::findAllFocusableComponents (focusContainer, comps);
  87. if (comps.size() > 0)
  88. {
  89. const int index = comps.indexOf (current);
  90. return comps [(index + comps.size() + delta) % comps.size()];
  91. }
  92. }
  93. }
  94. return nullptr;
  95. }
  96. }
  97. Component* KeyboardFocusTraverser::getNextComponent (Component* current)
  98. {
  99. return KeyboardFocusHelpers::getIncrementedComponent (current, 1);
  100. }
  101. Component* KeyboardFocusTraverser::getPreviousComponent (Component* current)
  102. {
  103. return KeyboardFocusHelpers::getIncrementedComponent (current, -1);
  104. }
  105. Component* KeyboardFocusTraverser::getDefaultComponent (Component* parentComponent)
  106. {
  107. Array <Component*> comps;
  108. if (parentComponent != nullptr)
  109. KeyboardFocusHelpers::findAllFocusableComponents (parentComponent, comps);
  110. return comps.getFirst();
  111. }
  112. END_JUCE_NAMESPACE