2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../../../core/juce_StandardHeader.h"
30 #include "juce_KeyboardFocusTraverser.h"
31 #include "../juce_Component.h"
34 //==============================================================================
35 KeyboardFocusTraverser::KeyboardFocusTraverser()
39 KeyboardFocusTraverser::~KeyboardFocusTraverser()
43 //==============================================================================
44 namespace KeyboardFocusHelpers
46 // This will sort a set of components, so that they are ordered in terms of
47 // left-to-right and then top-to-bottom.
48 class ScreenPositionComparator
51 ScreenPositionComparator() {}
53 static int compareElements (const Component
* const first
, const Component
* const second
)
55 int explicitOrder1
= first
->getExplicitFocusOrder();
56 if (explicitOrder1
<= 0)
57 explicitOrder1
= std::numeric_limits
<int>::max() / 2;
59 int explicitOrder2
= second
->getExplicitFocusOrder();
60 if (explicitOrder2
<= 0)
61 explicitOrder2
= std::numeric_limits
<int>::max() / 2;
63 if (explicitOrder1
!= explicitOrder2
)
64 return explicitOrder1
- explicitOrder2
;
66 const int diff
= first
->getY() - second
->getY();
68 return (diff
== 0) ? first
->getX() - second
->getX()
73 static void findAllFocusableComponents (Component
* const parent
, Array
<Component
*>& comps
)
75 if (parent
->getNumChildComponents() > 0)
77 Array
<Component
*> localComps
;
78 ScreenPositionComparator comparator
;
81 for (i
= parent
->getNumChildComponents(); --i
>= 0;)
83 Component
* const c
= parent
->getChildComponent (i
);
85 if (c
->isVisible() && c
->isEnabled())
86 localComps
.addSorted (comparator
, c
);
89 for (i
= 0; i
< localComps
.size(); ++i
)
91 Component
* const c
= localComps
.getUnchecked (i
);
93 if (c
->getWantsKeyboardFocus())
96 if (! c
->isFocusContainer())
97 findAllFocusableComponents (c
, comps
);
103 namespace KeyboardFocusHelpers
105 Component
* getIncrementedComponent (Component
* const current
, const int delta
)
107 Component
* focusContainer
= current
->getParentComponent();
109 if (focusContainer
!= nullptr)
111 while (focusContainer
->getParentComponent() != nullptr && ! focusContainer
->isFocusContainer())
112 focusContainer
= focusContainer
->getParentComponent();
114 if (focusContainer
!= nullptr)
116 Array
<Component
*> comps
;
117 KeyboardFocusHelpers::findAllFocusableComponents (focusContainer
, comps
);
119 if (comps
.size() > 0)
121 const int index
= comps
.indexOf (current
);
122 return comps
[(index
+ comps
.size() + delta
) % comps
.size()];
131 Component
* KeyboardFocusTraverser::getNextComponent (Component
* current
)
133 return KeyboardFocusHelpers::getIncrementedComponent (current
, 1);
136 Component
* KeyboardFocusTraverser::getPreviousComponent (Component
* current
)
138 return KeyboardFocusHelpers::getIncrementedComponent (current
, -1);
141 Component
* KeyboardFocusTraverser::getDefaultComponent (Component
* parentComponent
)
143 Array
<Component
*> comps
;
145 if (parentComponent
!= nullptr)
146 KeyboardFocusHelpers::findAllFocusableComponents (parentComponent
, comps
);
148 return comps
.getFirst();