using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Windows.Forms; using System.Text; using Aga.Controls.Tree.NodeControls; namespace Aga.Controls.Tree { public partial class TreeViewAdv { // overridden to return custom accessibility object instance protected override AccessibleObject CreateAccessibilityInstance() { return new TreeViewAdvAccessibleObject(this); } /// /// Represents the tree control itself in the acc tree /// public class TreeViewAdvAccessibleObject : Control.ControlAccessibleObject { private TreeViewAdv treeView; public TreeViewAdvAccessibleObject(TreeViewAdv owner) : base(owner) { treeView = owner; } /// /// The TreeViewAdv is an outline /// public override AccessibleRole Role { get { return AccessibleRole.Outline; } } /// /// The accessible name is the winforms control name /// public override string Name { get { return treeView.Name; } } /// /// Returns the node under the mouse pointer /// /// X screen coordinate. /// Y screen coordinate. /// The node under the mouse pointer. public override AccessibleObject HitTest(int x, int y) { TreeNodeAdv node = treeView.GetNodeAt(treeView.PointToClient(new Point(x, y))); if (node != null) return new AdvNodeAccessibleObject(node, null, this); if (treeView.RectangleToScreen(treeView.ClientRectangle).Contains(x, y)) return this; return null; } /// /// Returns a child node /// /// The index of the child node. /// The child node. public override AccessibleObject GetChild(int index) { return new AdvNodeAccessibleObject(treeView.Root.Nodes[index], null, this); } /// /// Returns the number of children. /// /// The number of children in the tree root. public override int GetChildCount() { return treeView.Root.Nodes.Count; } } /// /// Represents a node in the acc tree. /// public class AdvNodeAccessibleObject : AccessibleObject { TreeNodeAdv advNode; AdvNodeAccessibleObject parent; TreeViewAdvAccessibleObject owner; public AdvNodeAccessibleObject(TreeNodeAdv advNode, AdvNodeAccessibleObject parent, TreeViewAdvAccessibleObject owner) : base() { this.advNode = advNode; this.parent = parent; this.owner = owner; } /// /// The bounding rectangle in screen coordinates. /// public override Rectangle Bounds { get { if (!advNode.IsVisible) return Rectangle.Empty; Rectangle bounds = advNode.Tree.GetNodeBounds(advNode); Point p = advNode.Tree.ScrollPosition; int colHeaderY = advNode.Tree.UseColumns ? advNode.Tree.ColumnHeaderHeight : 0; bounds.Offset(-p.X, -p.Y * advNode.Tree.RowHeight + colHeaderY); return advNode.Tree.RectangleToScreen(bounds); } } /// /// The name of the default action. /// public override string DefaultAction { get { return advNode.IsExpanded ? "Collapse" : "Expand"; } } /// /// Performs the default action, which is either collapsing or expand the tree node /// public override void DoDefaultAction() { if (advNode.IsExpanded) advNode.Collapse(); else advNode.Expand(); } /// /// Either selects or focuses the tree node. /// /// either select or focus. public override void Select(AccessibleSelection flags) { if ((flags & AccessibleSelection.TakeSelection) > 0) { advNode.Tree.SelectedNode = advNode; } else if ((flags & AccessibleSelection.TakeFocus) > 0) { TreeNodeAdv parent = advNode.Parent; while (parent != null) { if (!parent.IsExpanded) parent.Expand(); parent = parent.Parent; } advNode.Tree.ScrollTo(advNode); advNode.Tree.Focus(); } } /// /// This does nothing because it is done by the tree. /// /// /// /// public override AccessibleObject HitTest(int x, int y) { return null; } /// /// The name is the first node control value which returns a string. /// public override string Name { get { foreach (NodeControlInfo info in advNode.Tree.GetNodeControls(advNode)) { BindableControl ctrl = info.Control as BindableControl; if (ctrl != null) { string val = ctrl.GetValue(advNode) as string; if (val != null) return val; } } return null; } } /// /// A number of state flags /// The Checked state uses the value of the first checkbox it finds. /// public override AccessibleStates State { get { AccessibleStates states = AccessibleStates.Selectable; if (advNode.IsExpanded) states |= AccessibleStates.Expanded; else states |= AccessibleStates.Collapsed; Rectangle treeRect = advNode.Tree.ClientRectangle; treeRect.Offset(advNode.Tree.PointToScreen(Point.Empty)); if (!advNode.IsVisible || !treeRect.IntersectsWith(Bounds) || treeRect.IsEmpty) states |= AccessibleStates.Invisible; if (advNode.IsSelected) states |= AccessibleStates.Selected; foreach (NodeControlInfo info in advNode.Tree.GetNodeControls(advNode)) { NodeCheckBox cb = info.Control as NodeCheckBox; if (cb != null) { if (((bool)cb.GetValue(advNode)) == true) states |= AccessibleStates.Checked; } } return states; } } public override AccessibleRole Role { get { return AccessibleRole.OutlineItem; } } /// /// Returns both child nodes and table cells, if available. /// /// /// public override AccessibleObject GetChild(int index) { int ctrlCount = advNode.Tree.Columns.Count; if (index < ctrlCount) return new AdvNodeCellAccessibleObject(advNode, index, this); else return new AdvNodeAccessibleObject(advNode.Nodes[index-ctrlCount], this, owner); } public override int GetChildCount() { return advNode.Nodes.Count + advNode.Tree.Columns.Count; } public override AccessibleObject Parent { get { if (advNode.Parent != advNode.Tree.Root) return parent != null ? parent : new AdvNodeAccessibleObject(advNode.Parent, null, owner); else return owner; } } } public class AdvNodeCellAccessibleObject : AccessibleObject { TreeNodeAdv advNode; AdvNodeAccessibleObject parent; int colIndex; public AdvNodeCellAccessibleObject(TreeNodeAdv advNode, int colIndex, AdvNodeAccessibleObject parent) : base() { this.advNode = advNode; this.colIndex = colIndex; this.parent = parent; } public override Rectangle Bounds { get { if (!advNode.IsVisible) return Rectangle.Empty; Rectangle colBounds = advNode.Tree.GetColumnBounds(colIndex); Rectangle nodeBounds = advNode.Tree.GetNodeBounds(advNode); Rectangle bounds = new Rectangle(colBounds.X, nodeBounds.Y, colBounds.Width, nodeBounds.Height); Point p = advNode.Tree.ScrollPosition; int colHeaderY = advNode.Tree.UseColumns ? advNode.Tree.ColumnHeaderHeight : 0; bounds.Offset(-p.X, -p.Y * advNode.Tree.RowHeight + colHeaderY); return advNode.Tree.RectangleToScreen(bounds); } } public override AccessibleRole Role { get { return AccessibleRole.Cell; } } public override string Name { get { string header = advNode.Tree.Columns[colIndex].Header; if (string.IsNullOrEmpty(header)) header = "Column" + colIndex; return header; } } /// /// The cell value is the contents of all node control values belonging to the column the cell is in. /// public override string Value { get { StringBuilder sb = new StringBuilder(); foreach (NodeControlInfo info in advNode.Tree.GetNodeControls(advNode)) { BindableControl ctrl = info.Control as BindableControl; if (ctrl != null && ctrl.ParentColumn != null && ctrl.ParentColumn.Index == colIndex) { object val = ctrl.GetValue(advNode); if (val != null) { sb.AppendLine(val.ToString()); } } } return sb.ToString().Trim(); } } public override AccessibleObject Parent { get { return parent; } } /// /// This does nothing because it is done by the tree. /// /// /// /// public override AccessibleObject HitTest(int x, int y) { return null; } } } }