* TreeView.cs: Don't draw the selected node when we lose
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / AccessibleObject.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 // 
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 // 
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2004-2005 Novell, Inc.
21 //
22 // Authors:
23 //      Peter Bartok    pbartok@novell.com
24 //
25
26
27 // NOT COMPLETE
28
29 using Accessibility;
30 using System.Drawing;
31 using System.Globalization;
32 using System.Reflection;
33 using System.Runtime.InteropServices;
34
35 namespace System.Windows.Forms {
36         [ComVisible(true)]
37         public class AccessibleObject : MarshalByRefObject, IReflect, IAccessible {
38                 #region Private Variables
39                 internal string         name;
40                 internal string         value;
41                 internal Control        owner;
42                 internal AccessibleRole role;
43                 internal string         default_action;
44                 internal string         description;
45                 internal string         help;
46                 internal string         keyboard_shortcut;
47                 #endregion      // Private Variables
48
49                 #region Public Constructors
50                 public AccessibleObject() {
51                         this.owner=null;
52                         this.value=null;
53                         this.name=null;
54                         this.role=AccessibleRole.Default;
55                         this.default_action=null;
56                         this.description=null;
57                         this.help=null;
58                         this.keyboard_shortcut=null;
59                 }
60                 #endregion      // Public Constructors
61
62                 #region Private Constructors
63                 internal AccessibleObject(Control owner) : this () {
64                         this.owner=owner;
65                 }
66                 #endregion      // Private Constructors
67
68                 #region Public Instance Properties
69                 public virtual Rectangle Bounds {
70                         get {
71                                 return owner.Bounds;
72                         }
73                 }
74
75                 public virtual string DefaultAction {
76                         get {
77                                 return default_action;
78                         }
79                 }
80
81                 public virtual string Description {
82                         get {
83                                 return description;
84                         }
85                 }
86
87                 public virtual string Help {
88                         get {
89                                 return help;
90                         }
91                 }
92
93                 public virtual string KeyboardShortcut {
94                         get {
95                                 return keyboard_shortcut;
96                         }
97                 }
98
99                 public virtual string Name {
100                         get {
101                                 return name;
102                         }
103
104                         set {
105                                 name=value;
106                         }
107                 }
108
109                 public virtual AccessibleObject Parent {
110                         get {
111                                 if ((owner!=null) && (owner.Parent!=null)) {
112                                         return owner.Parent.AccessibilityObject;
113                                 }
114                                 return null;
115                         }
116                 }
117
118                 public virtual AccessibleRole Role {
119                         get {
120                                 return role;
121                         }
122                 }
123
124                 public virtual AccessibleStates State {
125                         get {
126                                 AccessibleStates        state=AccessibleStates.None;
127
128                                 if (owner!=null) {
129                                         if (owner.Focused) {
130                                                 state |= AccessibleStates.Focused;
131                                         }
132
133                                         if (!owner.Visible) {
134                                                 state |= AccessibleStates.Invisible;
135                                         }
136                                 }
137                                 return state;
138                         }
139                 }
140
141                 public virtual string Value {
142                         get {
143                                 return this.value;
144                         }
145
146                         set {
147                                 this.value=value;
148                         }
149                 }
150                 #endregion      // Public Instance Properties
151
152                 #region Public Instance Methods
153                 public virtual void DoDefaultAction() {
154                         if (owner!=null) {
155                                 owner.DoDefaultAction();
156                         }
157                 }
158
159                 public virtual AccessibleObject GetChild(int index) {
160                         if (owner!=null) {
161                                 if (index<owner.child_controls.Count) {
162                                         return owner.child_controls[index].AccessibilityObject;
163                                 }
164                         }
165                         return null;
166                 }
167
168                 public virtual int GetChildCount() {
169                         if (owner!=null) {
170                                 return owner.child_controls.Count;
171                         }
172                         return -1;
173                 }
174
175                 public virtual AccessibleObject GetFocused() {
176                         Control result;
177
178                         if (owner.has_focus) {
179                                 return owner.AccessibilityObject;
180                         }
181
182                         result = FindFocusControl(owner);
183
184                         if (result != null) {
185                                 return result.AccessibilityObject;
186                         }
187
188                         return null;
189                 }
190
191                 public virtual int GetHelpTopic(out string FileName) {
192
193                         FileName = null;
194
195                         return -1;
196                 }
197
198                 public virtual AccessibleObject GetSelected() {
199                         Control result;
200
201                         if (owner.is_selected) {
202                                 return owner.AccessibilityObject;
203                         }
204
205                         result = FindSelectedControl(owner);
206
207                         if (result != null) {
208                                 return result.AccessibilityObject;
209                         }
210
211                         return null;
212                 }
213
214                 public virtual AccessibleObject HitTest(int x, int y) {
215                         Control result;
216
217                         result = FindHittestControl(owner, x, y);
218
219                         if (result != null) {
220                                 return result.AccessibilityObject;
221                         }
222
223                         return null;
224                 }
225
226                 public virtual AccessibleObject Navigate(AccessibleNavigation navdir) {
227                         int     index;
228
229                         // I'm not throwing exceptions if an object doesn't exist in the specified direction
230                         // Might not be too helpful to a blind dude trying to navigate. Instead we return
231                         // our own object
232
233                         if (owner.parent != null) {
234                                 index = owner.parent.child_controls.IndexOf(owner);
235                         } else {
236                                 index = -1;
237                         }
238
239                         switch (navdir) {
240                                 // Spatial navigation; limited to siblings
241                                 case AccessibleNavigation.Up: {
242                                         if (owner.parent != null) {
243                                                 for (int i=0; i<owner.parent.child_controls.Count; i++) {
244                                                         if ((owner != owner.parent.child_controls[i]) && (owner.parent.child_controls[i].Top<owner.Top)) {
245                                                                 return owner.parent.child_controls[i].AccessibilityObject;
246                                                         }
247                                                 }
248                                                 
249                                         }
250                                         return owner.AccessibilityObject;
251                                 }
252
253                                 case AccessibleNavigation.Down: {
254                                         if (owner.parent != null) {
255                                                 for (int i=0; i<owner.parent.child_controls.Count; i++) {
256                                                         if ((owner != owner.parent.child_controls[i]) && (owner.parent.child_controls[i].Top>owner.Bottom)) {
257                                                                 return owner.parent.child_controls[i].AccessibilityObject;
258                                                         }
259                                                 }
260                                                 
261                                         }
262                                         return owner.AccessibilityObject;
263                                 }
264
265                                 case AccessibleNavigation.Left: {
266                                         if (owner.parent != null) {
267                                                 for (int i=0; i<owner.parent.child_controls.Count; i++) {
268                                                         if ((owner != owner.parent.child_controls[i]) && (owner.parent.child_controls[i].Left<owner.Left)) {
269                                                                 return owner.parent.child_controls[i].AccessibilityObject;
270                                                         }
271                                                 }
272                                                 
273                                         }
274                                         return owner.AccessibilityObject;
275                                 }
276
277                                 case AccessibleNavigation.Right: {
278                                         if (owner.parent != null) {
279                                                 for (int i=0; i<owner.parent.child_controls.Count; i++) {
280                                                         if ((owner != owner.parent.child_controls[i]) && (owner.parent.child_controls[i].Left>owner.Right)) {
281                                                                 return owner.parent.child_controls[i].AccessibilityObject;
282                                                         }
283                                                 }
284                                                 
285                                         }
286                                         return owner.AccessibilityObject;
287                                 }
288
289                                 // Logical navigation
290                                 case AccessibleNavigation.Next: {
291                                         if (owner.parent != null) {
292                                                 if ((index+1)<owner.parent.child_controls.Count) {
293                                                         return owner.parent.child_controls[index+1].AccessibilityObject;
294                                                 } else {
295                                                         return owner.parent.child_controls[0].AccessibilityObject;
296                                                 }
297                                         } else {
298                                                 return owner.AccessibilityObject;
299                                         }
300                                 }
301
302                                 case AccessibleNavigation.Previous: {
303                                         if (owner.parent != null) {
304                                                 if (index>0) {
305                                                         return owner.parent.child_controls[index-1].AccessibilityObject;
306                                                 } else {
307                                                         return owner.parent.child_controls[owner.parent.child_controls.Count-1].AccessibilityObject;
308                                                 }
309                                         } else {
310                                                 return owner.AccessibilityObject;
311                                         }
312                                 }
313
314                                 case AccessibleNavigation.FirstChild: {
315                                         if (owner.child_controls.Count>0) {
316                                                 return owner.child_controls[0].AccessibilityObject;
317                                         } else {
318                                                 return owner.AccessibilityObject;
319                                         }
320                                 }
321
322                                 case AccessibleNavigation.LastChild: {
323                                         if (owner.child_controls.Count>0) {
324                                                 return owner.child_controls[owner.child_controls.Count-1].AccessibilityObject;
325                                         } else {
326                                                 return owner.AccessibilityObject;
327                                         }
328                                 }
329                         }
330
331                         return owner.AccessibilityObject;
332                 }
333
334                 public virtual void Select(AccessibleSelection flags) {
335                         if ((flags & AccessibleSelection.TakeFocus) != 0){
336                                 owner.Select(owner);
337                         }
338                         return;
339                 }
340                 #endregion      // Public Instance Methods
341
342                 #region Protected Instance Methods
343                 protected void UseStdAccessibleObjects(IntPtr handle) {
344                 }
345
346                 protected void UseStdAccessibleObjects(IntPtr handle, int objid) {
347                         UseStdAccessibleObjects(handle, 0);
348                 }
349                 #endregion      // Protected Instance Methods
350
351
352                 #region Internal Methods
353                 internal static Control FindFocusControl(Control parent) {
354                         Control child;
355
356                         for (int i=0; i < parent.child_controls.Count; i++) {
357                                 child=parent.child_controls[i];
358                                 if (child.has_focus) {
359                                         return child;
360                                 }
361                                 if (child.child_controls.Count>0) {
362                                         Control result;
363
364                                         result = FindFocusControl(child);
365                                         if (result != null) {
366                                                 return result;
367                                         }
368                                 }
369                         }
370                         return null;
371                 }
372
373                 internal static Control FindSelectedControl(Control parent) {
374                         Control child;
375
376                         for (int i=0; i < parent.child_controls.Count; i++) {
377                                 child=parent.child_controls[i];
378                                 if (child.has_focus) {
379                                         return child;
380                                 }
381                                 if (child.child_controls.Count>0) {
382                                         Control result;
383
384                                         result = FindSelectedControl(child);
385                                         if (result != null) {
386                                                 return result;
387                                         }
388                                 }
389                         }
390                         return null;
391                 }
392
393                 internal static Control FindHittestControl(Control parent, int x, int y) {
394                         Control child;
395                         Point   child_point;
396                         Point   hittest_point;
397
398                         hittest_point = new Point(x, y);
399
400                         child_point = parent.PointToClient(hittest_point);
401                         if (parent.ClientRectangle.Contains(child_point)) {
402                                 return parent;
403                         }
404
405                         for (int i=0; i < parent.child_controls.Count; i++) {
406                                 child=parent.child_controls[i];
407                                 child_point = child.PointToClient(hittest_point);
408                                 if (child.ClientRectangle.Contains(child_point)) {
409                                         return child;
410                                 }
411                                 if (child.child_controls.Count>0) {
412                                         Control result;
413
414                                         result = FindHittestControl(child, x, y);
415                                         if (result != null) {
416                                                 return result;
417                                         }
418                                 }
419                         }
420                         return null;
421                 }
422                 #endregion      // Internal Methods
423
424                 #region IReflection Methods and Properties
425                 FieldInfo IReflect.GetField(String name, BindingFlags bindingAttr) {
426                         throw new NotImplementedException();
427                 }       
428
429                 FieldInfo[] IReflect.GetFields(BindingFlags bindingAttr) {
430                         throw new NotImplementedException();
431                 }    
432
433                 MemberInfo[] IReflect.GetMember(String name, BindingFlags bindingAttr) {
434                         throw new NotImplementedException();
435                 }
436
437                 MemberInfo[] IReflect.GetMembers(BindingFlags bindingAttr) {
438                         throw new NotImplementedException();
439                 }
440
441                 MethodInfo IReflect.GetMethod(String name, BindingFlags bindingAttr) {
442                         throw new NotImplementedException();
443                 }
444
445                 MethodInfo IReflect.GetMethod(String name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) {
446                         throw new NotImplementedException();
447                 }
448
449                 MethodInfo[] IReflect.GetMethods(BindingFlags bindingAttr) {
450                         throw new NotImplementedException();
451                 }
452
453                 PropertyInfo IReflect.GetProperty(String name, BindingFlags bindingAttr) {
454                         throw new NotImplementedException();
455                 }
456
457                 PropertyInfo IReflect.GetProperty(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) {
458                         throw new NotImplementedException();
459                 }
460
461                 PropertyInfo[] IReflect.GetProperties(BindingFlags bindingAttr) {
462                         throw new NotImplementedException();
463                 }
464
465                 Object IReflect.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) {
466                         throw new NotImplementedException();
467                 }
468
469                 Type IReflect.UnderlyingSystemType {
470                         get {
471                                 throw new NotImplementedException();
472                         }
473                 }
474                 #endregion      // IReflection Methods and Properties
475
476                 #region IAccessible Methods and Properties
477                 void IAccessible.accDoDefaultAction(object childID) {
478                         throw new NotImplementedException();
479                 }
480
481                 int IAccessible.accChildCount {
482                         get {
483                                 throw new NotImplementedException();
484                         }
485                 }
486
487                 object IAccessible.accFocus {
488                         get {
489                                 throw new NotImplementedException();
490                         }
491                 }
492
493                 object IAccessible.accHitTest(int xLeft, int yTop) {
494                         throw new NotImplementedException();
495                 }
496
497                 void IAccessible.accLocation(out int pxLeft, out int pyTop, out int pcxWidth, out int pcyHeight, object childID) {
498                         throw new NotImplementedException();
499                 }
500
501                 object IAccessible.accNavigate(int navDir, object childID) {
502                         throw new NotImplementedException();
503                 }
504
505                 object IAccessible.accParent {
506                         get {
507                                 throw new NotImplementedException();
508                         }
509                 }
510
511                 void IAccessible.accSelect(int flagsSelect, object childID) {
512                         throw new NotImplementedException();
513                 }
514
515                 object IAccessible.accSelection {
516                         get {
517                                 throw new NotImplementedException();
518                         }
519                 }
520
521                 object IAccessible.get_accChild(object childID) {
522                         throw new NotImplementedException();
523                 }
524
525                 string IAccessible.get_accDefaultAction(object childID) {
526                         throw new NotImplementedException();
527                 }
528
529                 string IAccessible.get_accDescription(object childID) {
530                         throw new NotImplementedException();
531                 }
532
533                 string IAccessible.get_accHelp(object childID) {
534                         throw new NotImplementedException();
535                 }
536
537                 int IAccessible.get_accHelpTopic(out string pszHelpFile,object childID) {
538                         throw new NotImplementedException();
539                 }
540
541                 string IAccessible.get_accKeyboardShortcut(object childID) {
542                         throw new NotImplementedException();
543                 }
544
545                 string IAccessible.get_accName(object childID) {
546                         throw new NotImplementedException();
547                 }
548
549                 object IAccessible.get_accRole(object childID) {
550                         throw new NotImplementedException();
551                 }
552
553                 object IAccessible.get_accState(object childID) {
554                         throw new NotImplementedException();
555                 }
556
557                 string IAccessible.get_accValue(object childID) {
558                         throw new NotImplementedException();
559                 }
560
561                 void IAccessible.set_accName(object childID, string newName) {
562                         throw new NotImplementedException();
563                 }
564
565                 void IAccessible.set_accValue(object childID, string newValue) {
566                         throw new NotImplementedException();
567                 }
568                 #endregion      // IAccessible Methods and Properties
569         }
570 }