34 return detail::FocusHelpers::navigateFocus (current,
36 detail::FocusHelpers::NavigationDirection::forwards,
44 return detail::FocusHelpers::navigateFocus (current,
46 detail::FocusHelpers::NavigationDirection::backwards,
52 if (parentComponent !=
nullptr)
55 detail::FocusHelpers::findAllComponents (parentComponent,
59 if (! components.
empty())
60 return components.
front();
69 detail::FocusHelpers::findAllComponents (parentComponent,
86 void runTest()
override
89 const MessageManagerLock
mml;
91 beginTest (
"Basic traversal");
95 expect (
traverser.getDefaultComponent (&parent) == &parent.children.front());
97 for (
auto iter = parent.children.begin(); iter != parent.children.end(); ++iter)
101 for (
auto iter = parent.children.rbegin(); iter != parent.children.rend(); ++iter)
102 expect (
traverser.getPreviousComponent (&(*iter)) == (iter ==
std::prev (parent.children.rend()) ?
nullptr
103 : &(*
std::next (iter))));
107 [] (
const Component*
c1,
const Component&
c2) { return c1 == &c2; }));
110 beginTest (
"Disabled components are ignored");
112 checkIgnored ([] (Component& c) { c.setEnabled (
false); });
115 beginTest (
"Invisible components are ignored");
117 checkIgnored ([] (Component& c) { c.setVisible (
false); });
120 beginTest (
"Explicit focus order comes before unspecified");
132 beginTest (
"Explicit focus order comparison");
134 checkComponentProperties ([
this] (Component& child) { child.setExplicitFocusOrder (getRandom().nextInt ({ 1, 100 })); },
135 [] (
const Component&
c1,
const Component&
c2) {
return c1.getExplicitFocusOrder()
136 <=
c2.getExplicitFocusOrder(); });
139 beginTest (
"Left to right");
141 checkComponentProperties ([
this] (Component& child) { child.setTopLeftPosition (getRandom().nextInt ({ 0, 100 }), 0); },
142 [] (
const Component&
c1,
const Component&
c2) {
return c1.getX() <=
c2.getX(); });
145 beginTest (
"Top to bottom");
147 checkComponentProperties ([
this] (Component& child) { child.setTopLeftPosition (0, getRandom().nextInt ({ 0, 100 })); },
148 [] (
const Component&
c1,
const Component&
c2) {
return c1.getY() <=
c2.getY(); });
151 beginTest (
"Focus containers have their own focus");
158 root.addAndMakeVisible (container);
160 expect (
traverser.getDefaultComponent (&root) == &container);
161 expect (
traverser.getNextComponent (&container) ==
nullptr);
162 expect (
traverser.getPreviousComponent (&container) ==
nullptr);
164 expect (
traverser.getDefaultComponent (&container) == &container.children.front());
166 for (
auto iter = container.children.begin(); iter != container.children.end(); ++iter)
170 for (
auto iter = container.children.rbegin(); iter != container.children.rend(); ++iter)
171 expect (
traverser.getPreviousComponent (&(*iter)) == (iter ==
std::prev (container.children.rend()) ?
nullptr
174 expect (
traverser.getAllComponents (&root).size() == 1);
179 [] (
const Component*
c1,
const Component&
c2) { return c1 == &c2; }));
182 beginTest (
"Non-focus containers pass-through focus");
189 root.addAndMakeVisible (container);
191 expect (
traverser.getDefaultComponent (&root) == &container);
192 expect (
traverser.getNextComponent (&container) == &container.children.front());
193 expect (
traverser.getPreviousComponent (&container) ==
nullptr);
195 expect (
traverser.getDefaultComponent (&container) == &container.children.front());
197 for (
auto iter = container.children.begin(); iter != container.children.end(); ++iter)
201 for (
auto iter = container.children.rbegin(); iter != container.children.rend(); ++iter)
202 expect (
traverser.getPreviousComponent (&(*iter)) == (iter ==
std::prev (container.children.rend()) ? &container
205 expect (
traverser.getAllComponents (&root).size() == container.children.size() + 1);
214 for (
auto& child : children)
215 addAndMakeVisible (child);
226 for (
auto& child : parent.children)
229 auto* comp =
traverser.getDefaultComponent (&parent);
231 for (
const auto& child : parent.children)
251 auto iter = parent.children.begin();
The base class for all JUCE user-interface objects.
Component * findFocusContainer() const
Returns the focus container for this component.
@ none
The component will not act as a focus container.
@ focusContainer
The component will act as a top-level component within which focus is passed around.
bool isFocusContainer() const noexcept
Returns true if this component has been marked as a focus container.
std::vector< Component * > getAllComponents(Component *parentComponent) override
Returns all of the components that can receive focus within the given parent component in traversal o...
Component * getDefaultComponent(Component *parentComponent) override
Returns the component that should receive focus by default within the given parent component.
Component * getPreviousComponent(Component *current) override
Returns the component that should be given focus after the specified one when moving "backwards".
Component * getNextComponent(Component *current) override
Returns the component that should be given focus after the specified one when moving "forwards".
This is a base class for classes that perform a unit test.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...