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.

143 lines
4.7KB

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