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