bool TabNavigationWalker::Focus (UIElement *element, bool forwards) { bool focused = false; UIElement *current = element; UIElement *root = element; Types *types = Deployment::GetCurrent ()->GetTypes (); // If tabbing in reverse, we immediately go up a level from initial root as // we know we will not be focusing any of its children. if (!forwards && root->GetVisualParent ()) root = root->GetVisualParent (); do { // If we're starting a tab sequence and the parent of the current element is set to // the 'Once' navigation mode, we should not traverse the children if (!(root == current && root->GetVisualParent () && GetActiveNavigationMode (root->GetVisualParent (), types) == KeyboardNavigationModeOnce)) { focused |= WalkChildren (root, current, forwards, types); } if (!focused && GetActiveNavigationMode (root, types) == KeyboardNavigationModeCycle) return true; current = root; root = root->GetVisualParent (); } while (!focused && root); if (!focused) focused |= WalkChildren (current, NULL, forwards, types); return focused; }
bool Control::Focus (bool recurse) { if (!IsAttached ()) return false; /* according to msdn, these three things must be true for an element to be focusable: * * 1. the element must be visible * 2. the element must have IsTabStop = true * 3. the element must be part of the plugin's visual tree, and must have had its Loaded event fired. */ /* * If the current control is not focusable, we walk the visual tree and stop as soon * as we find the first focusable child. That then becomes focused */ Types *types = GetDeployment ()->GetTypes (); Surface *surface = GetDeployment ()->GetSurface (); DeepTreeWalker walker (this); while (UIElement *e = walker.Step ()) { if (!types->IsSubclassOf (e->GetObjectType (), Type::CONTROL)) continue; Control *c = (Control *)e; if (!c->GetIsEnabled ()) { if (!recurse) return false; walker.SkipBranch (); continue; } // A control is focusable if it is attached to a visual tree whose root // element has been loaded bool loaded = false; for (UIElement *check = this; !loaded && check != NULL; check = check->GetVisualParent ()) loaded |= check->IsLoaded (); if (loaded && c->GetRenderVisible () && c->GetIsTabStop ()) return surface->FocusElement (c); if (!recurse) return false; } return false; }