/* * Copyright (C) 2015 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.android.switchaccess; import android.graphics.Paint; import android.graphics.Rect; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Option Scanning node that holds other nodes for scanning. */ public class OptionScanSelectionNode implements OptionScanNode { protected OptionScanNode[] mChildren; private OptionScanSelectionNode mParent; /** * Selection nodes must be constructed with at least two things to select between * @param child0 The first item to select * @param child1 The second item to select * @param otherChildren Any other items to select */ public OptionScanSelectionNode( OptionScanNode child0, OptionScanNode child1, OptionScanNode... otherChildren) { mChildren = new OptionScanNode[otherChildren.length + 2]; mChildren[0] = child0; mChildren[1] = child1; System.arraycopy(otherChildren, 0, mChildren, 2, otherChildren.length); for (OptionScanNode child : mChildren) { child.setParent(this); } } @Override public Set<Rect> getRectsForNodeHighlight() { Set<Rect> rects = new HashSet<>(); for (OptionScanNode child : mChildren) { rects.addAll(child.getRectsForNodeHighlight()); } return Collections.unmodifiableSet(rects); } @Override public void recycle() { for (OptionScanNode child : mChildren) { child.recycle(); } } @Override public boolean equals(Object other) { if (!(other instanceof OptionScanSelectionNode)) { return false; } OptionScanSelectionNode otherNode = (OptionScanSelectionNode) other; if (otherNode.getChildCount() != getChildCount()) { return false; } for (int i = 0; i < mChildren.length; i++) { OptionScanNode child = mChildren[i]; if (!child.equals(otherNode.getChild(i))) { return false; } } return true; } @Override public void performAction() {} @Override public OptionScanSelectionNode getParent() { return mParent; } @Override public void setParent(OptionScanSelectionNode parent) { mParent = parent; } /** * Get the number of child nodes * @return The number of child nodes. */ public int getChildCount() { return mChildren.length; } /** * Get a specified child node. * @param index The index of the desired child. * @return The child requested, or {@code null} if * {@code ((index < 0) || (index >= getChildCount))} */ @SuppressWarnings("JavaDoc") public OptionScanNode getChild(int index) { if ((index < 0) || (index >= getChildCount())) { return null; } return mChildren[index]; } public void showSelections(OverlayController overlayController, Paint[] paints) { /* Display the options for the children. In addition if there are global views in the * overlay, such as the menu button when option scanning in enabled, highlight them as * well */ Rect globalMenuButton = overlayController.getMenuButtonLocation(); for (int childIndex = 0; childIndex < getChildCount(); ++childIndex) { Set<Rect> rectsForHighlight = new HashSet<>(); if ((paints.length > childIndex) && paints[childIndex] != null) { rectsForHighlight.addAll(getChild(childIndex).getRectsForNodeHighlight()); if (childIndex == getChildCount() - 1 && globalMenuButton != null) { rectsForHighlight.add(globalMenuButton); } overlayController.highlightPerimeterOfRects(rectsForHighlight, paints[childIndex]); } } } }