]> git.saurik.com Git - wxWidgets.git/blame - samples/access/accesstest.cpp
Add test for absence of events from wxSpinCtrlDouble ctor.
[wxWidgets.git] / samples / access / accesstest.cpp
CommitLineData
ae23a52a
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: accesstest.cpp
be5a51fb 3// Purpose: wxWidgets accessibility sample
ae23a52a
JS
4// Author: Julian Smart
5// Modified by:
6// Created: 2002-02-12
ae23a52a
JS
7// Copyright: (c) Julian Smart
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
19// For compilers that support precompilation, includes "wx/wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26// for all others, include the necessary headers (this file is usually all you
be5a51fb 27// need because it includes almost all "standard" wxWidgets headers)
ae23a52a
JS
28#ifndef WX_PRECOMP
29 #include "wx/wx.h"
30#endif
31
7d418908
JS
32#if wxUSE_ACCESSIBILITY
33 #include "wx/access.h"
34#endif // wxUSE_ACCESSIBILITY
35
8586126c 36#include "wx/splitter.h"
a37e4a07 37#include "wx/cshelp.h"
8586126c
JS
38
39#ifdef __WXMSW__
7d418908
JS
40 #include "windows.h"
41 #include <ole2.h>
42 #include <oleauto.h>
43
44 #if wxUSE_ACCESSIBILITY
45 #include <oleacc.h>
46 #endif // wxUSE_ACCESSIBILITY
47
48 #include "wx/msw/ole/oleutils.h"
49 #include "wx/msw/winundef.h"
8586126c 50
7d418908
JS
51 #ifndef OBJID_CLIENT
52 #define OBJID_CLIENT 0xFFFFFFFC
53 #endif
8586126c 54#endif
ae23a52a
JS
55
56// ----------------------------------------------------------------------------
57// resources
58// ----------------------------------------------------------------------------
59
60// the application icon (under Windows and OS/2 it is in resources)
e7092398 61#ifndef wxHAS_IMAGES_IN_RESOURCES
3cb332c1 62 #include "../sample.xpm"
ae23a52a
JS
63#endif
64
65// ----------------------------------------------------------------------------
66// private classes
67// ----------------------------------------------------------------------------
68
69// Define a new application type, each program should derive a class from wxApp
70class MyApp : public wxApp
71{
72public:
73 // override base class virtuals
74 // ----------------------------
75
76 // this one is called on application startup and is a good place for the app
77 // initialization (doing it here and not in the ctor allows to have an error
78 // return: if OnInit() returns false, the application terminates)
79 virtual bool OnInit();
8586126c 80
ae23a52a
JS
81};
82
7d418908
JS
83#if wxUSE_ACCESSIBILITY
84
ae23a52a
JS
85// Define a new frame type: this is going to be our main frame
86class MyFrame : public wxFrame
87{
88public:
89 // ctor(s)
90 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
91 long style = wxDEFAULT_FRAME_STYLE);
92
93 // event handlers (these functions should _not_ be virtual)
94 void OnQuit(wxCommandEvent& event);
8586126c 95 void OnQuery(wxCommandEvent& event);
ae23a52a
JS
96 void OnAbout(wxCommandEvent& event);
97
8586126c
JS
98 // Log messages to the text control
99 void Log(const wxString& text);
100
101 // Recursively give information about an object
102 void LogObject(int indent, IAccessible* obj);
103
2aefc528
JS
104 // Get info for a child (id > 0) or object (id == 0)
105 void GetInfo(IAccessible* accessible, int id, wxString& name, wxString& role);
ae23a52a 106private:
8586126c
JS
107 wxTextCtrl* m_textCtrl;
108
be5a51fb 109 // any class wishing to process wxWidgets events must use this macro
ae23a52a
JS
110 DECLARE_EVENT_TABLE()
111};
112
113// ----------------------------------------------------------------------------
114// constants
115// ----------------------------------------------------------------------------
116
117// IDs for the controls and the menu commands
118enum
119{
120 // menu items
121 AccessTest_Quit = 1,
122
8586126c
JS
123 // query the hierarchy
124 AccessTest_Query,
125
ae23a52a
JS
126 // it is important for the id corresponding to the "About" command to have
127 // this standard value as otherwise it won't be handled properly under Mac
128 // (where it is special and put into the "Apple" menu)
129 AccessTest_About = wxID_ABOUT
130};
131
132// ----------------------------------------------------------------------------
be5a51fb 133// event tables and other macros for wxWidgets
ae23a52a
JS
134// ----------------------------------------------------------------------------
135
be5a51fb 136// the event tables connect the wxWidgets events with the functions (event
ae23a52a
JS
137// handlers) which process them. It can be also done at run-time, but for the
138// simple menu events like this the static method is much simpler.
139BEGIN_EVENT_TABLE(MyFrame, wxFrame)
140 EVT_MENU(AccessTest_Quit, MyFrame::OnQuit)
8586126c 141 EVT_MENU(AccessTest_Query, MyFrame::OnQuery)
ae23a52a
JS
142 EVT_MENU(AccessTest_About, MyFrame::OnAbout)
143END_EVENT_TABLE()
144
7d418908
JS
145#endif // wxUSE_ACCESSIBILITY
146
be5a51fb 147// Create a new application object: this macro will allow wxWidgets to create
ae23a52a
JS
148// the application object during program execution (it's better than using a
149// static object for many reasons) and also declares the accessor function
150// wxGetApp() which will return the reference of the right type (i.e. MyApp and
151// not wxApp)
152IMPLEMENT_APP(MyApp)
153
154// ============================================================================
155// implementation
156// ============================================================================
157
158// ----------------------------------------------------------------------------
159// the application class
160// ----------------------------------------------------------------------------
161
162// 'Main program' equivalent: the program execution "starts" here
163bool MyApp::OnInit()
164{
45e6e6f8
VZ
165 if ( !wxApp::OnInit() )
166 return false;
167
7d418908 168#if wxUSE_ACCESSIBILITY
a37e4a07
JS
169 // Note: JAWS for Windows will only speak the context-sensitive
170 // help if you use this help provider:
171 // wxHelpProvider::Set(new wxHelpControllerHelpProvider(m_helpController)).
172 // JAWS does not seem to be getting the help text from
173 // the wxAccessible object.
174 wxHelpProvider::Set(new wxSimpleHelpProvider());
175
ae23a52a 176 // create the main application window
9a83f860 177 MyFrame *frame = new MyFrame(wxT("AccessTest wxWidgets App"),
ae23a52a
JS
178 wxPoint(50, 50), wxSize(450, 340));
179
180 // and show it (the frames, unlike simple controls, are not shown when
181 // created initially)
5014bb3a 182 frame->Show(true);
ae23a52a
JS
183
184 // success: wxApp::OnRun() will be called which will enter the main message
5014bb3a 185 // loop and the application will run. If we returned false here, the
ae23a52a 186 // application would exit immediately.
5014bb3a 187 return true;
7d418908 188#else
9a83f860 189 wxMessageBox( wxT("This sample has to be compiled with wxUSE_ACCESSIBILITY"), wxT("Building error"), wxOK);
5014bb3a 190 return false;
7d418908 191#endif // wxUSE_ACCESSIBILITY
ae23a52a
JS
192}
193
7d418908
JS
194#if wxUSE_ACCESSIBILITY
195
ae23a52a
JS
196class FrameAccessible: public wxWindowAccessible
197{
198public:
199 FrameAccessible(wxWindow* win): wxWindowAccessible(win) {}
200
201 // Gets the name of the specified object.
202 virtual wxAccStatus GetName(int childId, wxString* name)
203 {
ae23a52a
JS
204 if (childId == wxACC_SELF)
205 {
206 * name = wxT("Julian's Frame");
207 return wxACC_OK;
208 }
209 else
ae23a52a
JS
210 return wxACC_NOT_IMPLEMENTED;
211 }
212};
213
214class ScrolledWindowAccessible: public wxWindowAccessible
215{
216public:
217 ScrolledWindowAccessible(wxWindow* win): wxWindowAccessible(win) {}
218
219 // Gets the name of the specified object.
220 virtual wxAccStatus GetName(int childId, wxString* name)
221 {
222 if (childId == wxACC_SELF)
223 {
224 * name = wxT("My scrolled window");
225 return wxACC_OK;
226 }
227 else
228 return wxACC_NOT_IMPLEMENTED;
229 }
230};
231
84969af7
JS
232class SplitterWindowAccessible: public wxWindowAccessible
233{
234public:
235 SplitterWindowAccessible(wxWindow* win): wxWindowAccessible(win) {}
236
237 // Gets the name of the specified object.
a37e4a07 238 virtual wxAccStatus GetName(int childId, wxString* name);
84969af7
JS
239
240 // Can return either a child object, or an integer
241 // representing the child element, starting from 1.
a37e4a07 242 virtual wxAccStatus HitTest(const wxPoint& pt, int* childId, wxAccessible** childObject);
84969af7
JS
243
244 // Returns the rectangle for this object (id = 0) or a child element (id > 0).
a37e4a07 245 virtual wxAccStatus GetLocation(wxRect& rect, int elementId);
84969af7
JS
246
247 // Navigates from fromId to toId/toObject.
a37e4a07
JS
248 virtual wxAccStatus Navigate(wxNavDir navDir, int fromId,
249 int* toId, wxAccessible** toObject);
84969af7
JS
250
251 // Gets the number of children.
a37e4a07 252 virtual wxAccStatus GetChildCount(int* childCount);
84969af7
JS
253
254 // Gets the specified child (starting from 1).
255 // If *child is NULL and return value is wxACC_OK,
256 // this means that the child is a simple element and
257 // not an accessible object.
a37e4a07 258 virtual wxAccStatus GetChild(int childId, wxAccessible** child);
84969af7
JS
259
260 // Gets the parent, or NULL.
a37e4a07 261 virtual wxAccStatus GetParent(wxAccessible** parent);
84969af7
JS
262
263 // Performs the default action. childId is 0 (the action for this object)
264 // or > 0 (the action for a child).
265 // Return wxACC_NOT_SUPPORTED if there is no default action for this
266 // window (e.g. an edit control).
a37e4a07 267 virtual wxAccStatus DoDefaultAction(int childId);
84969af7
JS
268
269 // Gets the default action for this object (0) or > 0 (the action for a child).
270 // Return wxACC_OK even if there is no action. actionName is the action, or the empty
271 // string if there is no action.
272 // The retrieved string describes the action that is performed on an object,
273 // not what the object does as a result. For example, a toolbar button that prints
274 // a document has a default action of "Press" rather than "Prints the current document."
a37e4a07 275 virtual wxAccStatus GetDefaultAction(int childId, wxString* actionName);
84969af7
JS
276
277 // Returns the description for this object or a child.
a37e4a07 278 virtual wxAccStatus GetDescription(int childId, wxString* description);
84969af7
JS
279
280 // Returns help text for this object or a child, similar to tooltip text.
a37e4a07 281 virtual wxAccStatus GetHelpText(int childId, wxString* helpText);
84969af7
JS
282
283 // Returns the keyboard shortcut for this object or child.
284 // Return e.g. ALT+K
a37e4a07 285 virtual wxAccStatus GetKeyboardShortcut(int childId, wxString* shortcut);
84969af7
JS
286
287 // Returns a role constant.
a37e4a07 288 virtual wxAccStatus GetRole(int childId, wxAccRole* role);
84969af7
JS
289
290 // Returns a state constant.
a37e4a07 291 virtual wxAccStatus GetState(int childId, long* state);
84969af7
JS
292
293 // Returns a localized string representing the value for the object
294 // or child.
a37e4a07 295 virtual wxAccStatus GetValue(int childId, wxString* strValue);
84969af7
JS
296
297 // Selects the object or child.
a37e4a07 298 virtual wxAccStatus Select(int childId, wxAccSelectionFlags selectFlags);
84969af7
JS
299
300 // Gets the window with the keyboard focus.
301 // If childId is 0 and child is NULL, no object in
302 // this subhierarchy has the focus.
303 // If this object has the focus, child should be 'this'.
a37e4a07 304 virtual wxAccStatus GetFocus(int* childId, wxAccessible** child);
84969af7
JS
305
306 // Gets a variant representing the selected children
307 // of this object.
308 // Acceptable values:
5014bb3a 309 // - a null variant (IsNull() returns true)
84969af7
JS
310 // - a list variant (GetType() == wxT("list"))
311 // - an integer representing the selected child element,
312 // or 0 if this object is selected (GetType() == wxT("long"))
313 // - a "void*" pointer to a wxAccessible child object
a37e4a07 314 virtual wxAccStatus GetSelections(wxVariant* selections);
84969af7
JS
315
316};
317
ae23a52a
JS
318// ----------------------------------------------------------------------------
319// main frame
320// ----------------------------------------------------------------------------
321
322// frame constructor
323MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
5014bb3a 324 : wxFrame(NULL, wxID_ANY, title, pos, size, style)
ae23a52a 325{
8586126c
JS
326 m_textCtrl = NULL;
327
a37e4a07 328 SetAccessible(new FrameAccessible(this));
ae23a52a
JS
329
330 // set the frame icon
3cb332c1 331 SetIcon(wxICON(sample));
ae23a52a
JS
332
333#if wxUSE_MENUS
334 // create a menu bar
335 wxMenu *menuFile = new wxMenu;
336
337 // the "About" item should be in the help menu
338 wxMenu *helpMenu = new wxMenu;
2d143b66 339 helpMenu->Append(AccessTest_About, wxT("&About"), wxT("Show about dialog"));
ae23a52a 340
9a83f860 341 menuFile->Append(AccessTest_Query, wxT("Query"), wxT("Query the window hierarchy"));
8586126c 342 menuFile->AppendSeparator();
9a83f860 343 menuFile->Append(AccessTest_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
ae23a52a
JS
344
345 // now append the freshly created menu to the menu bar...
346 wxMenuBar *menuBar = new wxMenuBar();
9a83f860
VZ
347 menuBar->Append(menuFile, wxT("&File"));
348 menuBar->Append(helpMenu, wxT("&Help"));
ae23a52a
JS
349
350 // ... and attach this menu bar to the frame
351 SetMenuBar(menuBar);
352#endif // wxUSE_MENUS
353
2aefc528 354#if 0 // wxUSE_STATUSBAR
ae23a52a
JS
355 // create a status bar just for fun (by default with 1 pane only)
356 CreateStatusBar(2);
9a83f860 357 SetStatusText(wxT("Welcome to wxWidgets!"));
ae23a52a
JS
358#endif // wxUSE_STATUSBAR
359
a37e4a07 360
5014bb3a 361 wxSplitterWindow* splitter = new wxSplitterWindow(this, wxID_ANY);
a37e4a07 362 splitter->SetAccessible(new SplitterWindowAccessible(splitter));
8586126c 363
5014bb3a 364 wxListBox* listBox = new wxListBox(splitter, wxID_ANY);
a37e4a07
JS
365 listBox->Append(wxT("Cabbages"));
366 listBox->Append(wxT("Kings"));
367 listBox->Append(wxT("Sealing wax"));
368 listBox->Append(wxT("Strings"));
8586126c 369 listBox->CreateAccessible();
be5a51fb 370 listBox->SetHelpText(wxT("This is a sample wxWidgets listbox, with a number of items in it."));
8586126c 371
5014bb3a 372 m_textCtrl = new wxTextCtrl(splitter, wxID_ANY, wxT(""), wxDefaultPosition,
8586126c
JS
373 wxDefaultSize, wxTE_MULTILINE);
374 m_textCtrl->CreateAccessible();
be5a51fb 375 m_textCtrl->SetHelpText(wxT("This is a sample wxWidgets multiline text control."));
8586126c
JS
376
377 splitter->SplitHorizontally(listBox, m_textCtrl, 150);
378
379#if 0
5014bb3a 380 wxScrolledWindow* scrolledWindow = new wxScrolledWindow(this, wxID_ANY);
ae23a52a
JS
381 scrolledWindow->SetAccessible(new ScrolledWindowAccessible(scrolledWindow));
382#endif
383}
384
385
386// event handlers
387
388void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
389{
5014bb3a
WS
390 // true is to force the frame to close
391 Close(true);
ae23a52a
JS
392}
393
394void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
395{
396 wxString msg;
9a83f860
VZ
397 msg.Printf( wxT("This is the About dialog of the AccessTest sample.\n")
398 wxT("Welcome to %s"), wxVERSION_STRING);
ae23a52a 399
9a83f860 400 wxMessageBox(msg, wxT("About AccessTest"), wxOK | wxICON_INFORMATION, this);
ae23a52a 401}
8586126c
JS
402
403void MyFrame::OnQuery(wxCommandEvent& WXUNUSED(event))
404{
405 m_textCtrl->Clear();
406 IAccessible* accessibleFrame = NULL;
407 if (S_OK != AccessibleObjectFromWindow((HWND) GetHWND(), OBJID_CLIENT,
408 IID_IAccessible, (void**) & accessibleFrame))
409 {
410 Log(wxT("Could not get object."));
411 return;
412 }
413 if (accessibleFrame)
414 {
2aefc528 415 //Log(wxT("Got an IAccessible for the frame."));
8586126c 416 LogObject(0, accessibleFrame);
2aefc528
JS
417 Log(wxT("Checking children using AccessibleChildren()..."));
418
419 // Now check the AccessibleChildren function works OK
420 long childCount = 0;
421 if (S_OK != accessibleFrame->get_accChildCount(& childCount))
422 {
423 Log(wxT("Could not get number of children."));
424 accessibleFrame->Release();
425 return;
426 }
427 else if (childCount == 0)
428 {
429 Log(wxT("No children."));
430 accessibleFrame->Release();
431 return;
432 }
ce00f59b 433
2aefc528
JS
434
435 long obtained = 0;
436 VARIANT *var = new VARIANT[childCount];
437 int i;
438 for (i = 0; i < childCount; i++)
439 {
440 VariantInit(& (var[i]));
441 var[i].vt = VT_DISPATCH;
442 }
ce00f59b 443
2aefc528
JS
444 if (S_OK == AccessibleChildren(accessibleFrame, 0, childCount, var, &obtained))
445 {
446 for (i = 0; i < childCount; i++)
447 {
448 IAccessible* childAccessible = NULL;
449 if (var[i].pdispVal)
450 {
451 if (var[i].pdispVal->QueryInterface(IID_IAccessible, (LPVOID*) & childAccessible) == S_OK)
452 {
453 var[i].pdispVal->Release();
ce00f59b 454
2aefc528
JS
455 wxString name, role;
456 GetInfo(childAccessible, 0, name, role);
457 wxString str;
458 str.Printf(wxT("Found child %s/%s"), name.c_str(), role.c_str());
459 Log(str);
460 childAccessible->Release();
461 }
462 else
463 {
464 var[i].pdispVal->Release();
465 }
466 }
467 }
468 }
469 else
470 {
471 Log(wxT("AccessibleChildren failed."));
472 }
473 delete[] var;
474
475
8586126c
JS
476 accessibleFrame->Release();
477 }
478}
479
480// Log messages to the text control
481void MyFrame::Log(const wxString& text)
482{
483 if (m_textCtrl)
484 {
485 wxString text2(text);
486 text2.Replace(wxT("\n"), wxT(" "));
487 text2.Replace(wxT("\r"), wxT(" "));
488 m_textCtrl->SetInsertionPointEnd();
489 m_textCtrl->WriteText(text2 + wxT("\n"));
490 }
491}
492
493// Recursively give information about an object
494void MyFrame::LogObject(int indent, IAccessible* obj)
495{
2aefc528
JS
496 wxString name, role;
497 if (indent == 0)
8586126c 498 {
2aefc528
JS
499 GetInfo(obj, 0, name, role);
500
8586126c 501 wxString str;
2aefc528 502 str.Printf(wxT("Name = %s; Role = %s"), name.c_str(), role.c_str());
5014bb3a 503 str.Pad(indent, wxT(' '), false);
8586126c
JS
504 Log(str);
505 }
8586126c
JS
506
507 long childCount = 0;
508 if (S_OK == obj->get_accChildCount(& childCount))
509 {
510 wxString str;
511 str.Printf(wxT("There are %d children."), (int) childCount);
5014bb3a 512 str.Pad(indent, wxT(' '), false);
8586126c 513 Log(str);
2aefc528 514 Log(wxT(""));
8586126c
JS
515 }
516
517 int i;
518 for (i = 1; i <= childCount; i++)
519 {
2aefc528
JS
520 GetInfo(obj, i, name, role);
521
522 wxString str;
523 str.Printf(wxT("%d) Name = %s; Role = %s"), i, name.c_str(), role.c_str());
5014bb3a 524 str.Pad(indent, wxT(' '), false);
2aefc528
JS
525 Log(str);
526
8586126c
JS
527 VARIANT var;
528 VariantInit(& var);
529 var.vt = VT_I4;
530 var.lVal = i;
531 IDispatch* pDisp = NULL;
532 IAccessible* childObject = NULL;
533
8586126c
JS
534 if (S_OK == obj->get_accChild(var, & pDisp) && pDisp)
535 {
536 wxString str;
537 str.Printf(wxT("This is a real object."));
5014bb3a 538 str.Pad(indent+4, wxT(' '), false);
8586126c
JS
539 Log(str);
540
541 if (pDisp->QueryInterface(IID_IAccessible, (LPVOID*) & childObject) == S_OK)
542 {
543 LogObject(indent + 4, childObject);
544 childObject->Release();
545 }
546 pDisp->Release();
547 }
548 else
549 {
550 wxString str;
551 str.Printf(wxT("This is an element."));
5014bb3a 552 str.Pad(indent+4, wxT(' '), false);
8586126c
JS
553 Log(str);
554 }
2aefc528 555 // Log(wxT(""));
8586126c
JS
556 }
557
558}
559
2aefc528
JS
560// Get info for a child (id > 0) or object (id == 0)
561void MyFrame::GetInfo(IAccessible* accessible, int id, wxString& name, wxString& role)
562{
563 VARIANT var;
564 VariantInit(& var);
565 var.vt = VT_I4;
566 var.lVal = id;
ce00f59b 567
2aefc528
JS
568 BSTR bStrName = 0;
569 HRESULT hResult = accessible->get_accName(var, & bStrName);
ce00f59b 570
2aefc528
JS
571 if (hResult == S_OK)
572 {
573 name = wxConvertStringFromOle(bStrName);
574 SysFreeString(bStrName);
575 }
576 else
577 {
578 name = wxT("NO NAME");
579 }
ce00f59b 580
2aefc528
JS
581 VARIANT varRole;
582 VariantInit(& varRole);
ce00f59b 583
2aefc528 584 hResult = accessible->get_accRole(var, & varRole);
ce00f59b 585
2aefc528
JS
586 if (hResult == S_OK && varRole.vt == VT_I4)
587 {
588 wxChar buf[256];
589 GetRoleText(varRole.lVal, buf, 256);
ce00f59b 590
2aefc528
JS
591 role = buf;
592 }
593 else
594 {
595 role = wxT("NO ROLE");
ce00f59b 596 }
2aefc528 597}
a37e4a07
JS
598
599/*
600 * SplitterWindowAccessible implementation
601 */
602
603// Gets the name of the specified object.
604wxAccStatus SplitterWindowAccessible::GetName(int childId, wxString* name)
605{
606 if (childId == wxACC_SELF)
607 {
608 * name = wxT("Splitter window");
609 return wxACC_OK;
610 }
611 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
612 if (splitter)
613 {
614 if (splitter->IsSplit())
615 {
616 // Two windows, and the sash.
617 if (childId == 1 || childId == 3)
618 return wxACC_NOT_IMPLEMENTED;
619 else if (childId == 2)
620 {
621 *name = wxT("Sash");
622 return wxACC_OK;
623 }
624 }
625 }
626 // Let the framework handle the other cases.
627 return wxACC_NOT_IMPLEMENTED;
628}
629
630// Can return either a child object, or an integer
631// representing the child element, starting from 1.
7d418908 632wxAccStatus SplitterWindowAccessible::HitTest(const wxPoint& pt, int* childId, wxAccessible** WXUNUSED(childObject))
a37e4a07
JS
633{
634 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
635 if (splitter)
636 {
637 if (splitter->IsSplit())
638 {
639 wxPoint clientPt = splitter->ScreenToClient(pt);
640 if (splitter->SashHitTest(clientPt.x, clientPt.y, 1))
641 {
642 // We're over the sash
643 *childId = 2;
644 return wxACC_OK;
645 }
646 }
647 }
648 // Let the framework handle the other cases.
649 return wxACC_NOT_IMPLEMENTED;
650}
651
652// Returns the rectangle for this object (id = 0) or a child element (id > 0).
653wxAccStatus SplitterWindowAccessible::GetLocation(wxRect& rect, int elementId)
654{
655 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
656 if (splitter && elementId == 2 && splitter->IsSplit())
657 {
658 wxSize clientSize = splitter->GetClientSize();
659 if (splitter->GetSplitMode() == wxSPLIT_VERTICAL)
660 {
661 rect.x = splitter->GetSashPosition();
662 rect.y = 0;
663 rect.SetPosition(splitter->ClientToScreen(rect.GetPosition()));
664 rect.width = splitter->GetSashSize();
665 rect.height = clientSize.y;
666 }
667 else
668 {
669 rect.x = 0;
670 rect.y = splitter->GetSashPosition();
671 rect.SetPosition(splitter->ClientToScreen(rect.GetPosition()));
672 rect.width = clientSize.x;
673 rect.height = splitter->GetSashSize();
674 }
675 return wxACC_OK;
676 }
677 // Let the framework handle the other cases.
678 return wxACC_NOT_IMPLEMENTED;
679}
680
681// Navigates from fromId to toId/toObject.
682wxAccStatus SplitterWindowAccessible::Navigate(wxNavDir navDir, int fromId,
683 int* toId, wxAccessible** toObject)
684{
685 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
686 if (splitter && splitter->IsSplit())
687 {
688 switch (navDir)
689 {
690 case wxNAVDIR_DOWN:
691 {
7d418908 692 if (splitter->GetSplitMode() != wxSPLIT_VERTICAL)
a37e4a07
JS
693 {
694 if (fromId == 1)
695 {
696 *toId = 2;
697 *toObject = NULL;
698 return wxACC_OK;
699 }
700 else if (fromId == 2)
701 {
702 *toId = 3;
703 *toObject = splitter->GetWindow2()->GetAccessible();
704 return wxACC_OK;
705 }
a37e4a07 706 }
7d418908
JS
707 return wxACC_FALSE;
708 #if 0
709 // below line is not executed due to earlier return
a37e4a07 710 break;
7d418908 711 #endif
a37e4a07
JS
712 }
713 case wxNAVDIR_FIRSTCHILD:
714 {
715 if (fromId == 2)
716 return wxACC_FALSE;
717 }
718 break;
ce00f59b 719
a37e4a07
JS
720 case wxNAVDIR_LASTCHILD:
721 {
722 if (fromId == 2)
723 return wxACC_FALSE;
724 }
725 break;
ce00f59b 726
a37e4a07
JS
727 case wxNAVDIR_LEFT:
728 {
7d418908 729 if (splitter->GetSplitMode() != wxSPLIT_HORIZONTAL)
a37e4a07
JS
730 {
731 if (fromId == 3)
732 {
733 *toId = 2;
734 *toObject = NULL;
735 return wxACC_OK;
736 }
737 else if (fromId == 2)
738 {
739 *toId = 1;
740 *toObject = splitter->GetWindow1()->GetAccessible();
741 return wxACC_OK;
742 }
a37e4a07 743 }
7d418908 744 return wxACC_FALSE;
a37e4a07 745 }
7d418908
JS
746 #if 0
747 // below line is not executed due to earlier return
a37e4a07 748 break;
7d418908 749 #endif
ce00f59b 750
a37e4a07
JS
751 case wxNAVDIR_NEXT:
752 {
753 if (fromId == 1)
754 {
755 *toId = 2;
756 *toObject = NULL;
757 return wxACC_OK;
758 }
759 else if (fromId == 2)
760 {
761 *toId = 3;
762 *toObject = splitter->GetWindow2()->GetAccessible();
763 return wxACC_OK;
764 }
a37e4a07
JS
765 return wxACC_FALSE;
766 }
7d418908
JS
767 #if 0
768 // below line is not executed due to earlier return
a37e4a07 769 break;
7d418908 770 #endif
ce00f59b 771
a37e4a07
JS
772 case wxNAVDIR_PREVIOUS:
773 {
774 if (fromId == 3)
775 {
776 *toId = 2;
777 *toObject = NULL;
778 return wxACC_OK;
779 }
780 else if (fromId == 2)
781 {
782 *toId = 1;
783 *toObject = splitter->GetWindow1()->GetAccessible();
784 return wxACC_OK;
785 }
a37e4a07
JS
786 return wxACC_FALSE;
787 }
7d418908
JS
788 #if 0
789 // below line is not executed due to earlier return
a37e4a07 790 break;
7d418908 791 #endif
ce00f59b 792
a37e4a07
JS
793 case wxNAVDIR_RIGHT:
794 {
7d418908 795 if (splitter->GetSplitMode() != wxSPLIT_HORIZONTAL)
a37e4a07
JS
796 {
797 if (fromId == 1)
798 {
799 *toId = 2;
800 *toObject = NULL;
801 return wxACC_OK;
802 }
803 else if (fromId == 2)
804 {
805 *toId = 3;
806 *toObject = splitter->GetWindow2()->GetAccessible();
807 return wxACC_OK;
808 }
a37e4a07 809 }
7d418908 810 // Can't go right spatially if split horizontally.
ce00f59b 811 return wxACC_FALSE;
a37e4a07 812 }
7d418908
JS
813 #if 0
814 // below line is not executed due to earlier return
a37e4a07 815 break;
7d418908 816 #endif
ce00f59b 817
a37e4a07
JS
818 case wxNAVDIR_UP:
819 {
7d418908 820 if (splitter->GetSplitMode() != wxSPLIT_VERTICAL)
a37e4a07
JS
821 {
822 if (fromId == 3)
823 {
824 *toId = 2;
825 return wxACC_OK;
826 }
827 else if (fromId == 2)
828 {
829 *toId = 1;
830 *toObject = splitter->GetWindow1()->GetAccessible();
831 return wxACC_OK;
832 }
a37e4a07
JS
833 }
834
7d418908 835 // Can't go up spatially if split vertically.
ce00f59b 836 return wxACC_FALSE;
7d418908
JS
837 #if 0
838 // below line is not executed due to earlier return
a37e4a07 839 break;
7d418908 840 #endif
a37e4a07
JS
841 }
842 }
ce00f59b 843
a37e4a07
JS
844 }
845 // Let the framework handle the other cases.
846 return wxACC_NOT_IMPLEMENTED;
847}
848
849// Gets the number of children.
850wxAccStatus SplitterWindowAccessible::GetChildCount(int* childCount)
851{
852 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
853 if (splitter)
854 {
855 if (splitter->IsSplit())
856 {
857 // Two windows, and the sash.
858 *childCount = 3;
859 return wxACC_OK;
860 }
861 else
862 {
863 // No sash -- 1 or 0 windows.
864 if (splitter->GetWindow1() || splitter->GetWindow2())
865 {
866 *childCount = 1;
867 return wxACC_OK;
868 }
869 else
870 {
871 *childCount = 0;
872 return wxACC_OK;
873 }
874 }
875 }
876 // Let the framework handle the other cases.
877 return wxACC_NOT_IMPLEMENTED;
878}
879
880// Gets the specified child (starting from 1).
881// If *child is NULL and return value is wxACC_OK,
882// this means that the child is a simple element and
883// not an accessible object.
884wxAccStatus SplitterWindowAccessible::GetChild(int childId, wxAccessible** child)
885{
886 if (childId == wxACC_SELF)
887 {
888 *child = this;
889 return wxACC_OK;
890 }
891
892 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
893 if (splitter)
894 {
895 if (splitter->IsSplit())
896 {
897 // Two windows, and the sash.
898 if (childId == 1)
899 {
900 *child = splitter->GetWindow1()->GetAccessible();
901 }
902 else if (childId == 2)
903 {
904 *child = NULL; // Sash
905 }
906 else if (childId == 3)
907 {
908 *child = splitter->GetWindow2()->GetAccessible();
909 }
910 else
911 {
912 return wxACC_FAIL;
913 }
914 return wxACC_OK;
915 }
916 else
917 {
918 // No sash -- 1 or 0 windows.
919 if (childId == 1)
920 {
921 if (splitter->GetWindow1())
922 {
923 *child = splitter->GetWindow1()->GetAccessible();
924 return wxACC_OK;
925 }
926 else if (splitter->GetWindow2())
927 {
928 *child = splitter->GetWindow2()->GetAccessible();
929 return wxACC_OK;
930 }
931 else
932 {
933 return wxACC_FAIL;
934 }
935 }
936 else
937 return wxACC_FAIL;
938 }
939 }
940 // Let the framework handle the other cases.
941 return wxACC_NOT_IMPLEMENTED;
942}
943
944// Gets the parent, or NULL.
7d418908 945wxAccStatus SplitterWindowAccessible::GetParent(wxAccessible** WXUNUSED(parent))
a37e4a07
JS
946{
947 return wxACC_NOT_IMPLEMENTED;
948}
949
950// Performs the default action. childId is 0 (the action for this object)
951// or > 0 (the action for a child).
952// Return wxACC_NOT_SUPPORTED if there is no default action for this
953// window (e.g. an edit control).
7d418908 954wxAccStatus SplitterWindowAccessible::DoDefaultAction(int WXUNUSED(childId))
a37e4a07
JS
955{
956 return wxACC_NOT_IMPLEMENTED;
957}
958
959// Gets the default action for this object (0) or > 0 (the action for a child).
960// Return wxACC_OK even if there is no action. actionName is the action, or the empty
961// string if there is no action.
962// The retrieved string describes the action that is performed on an object,
963// not what the object does as a result. For example, a toolbar button that prints
964// a document has a default action of "Press" rather than "Prints the current document."
7d418908 965wxAccStatus SplitterWindowAccessible::GetDefaultAction(int childId, wxString* WXUNUSED(actionName))
a37e4a07
JS
966{
967 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
968 if (splitter && splitter->IsSplit() && childId == 2)
969 {
970 // No default action for the splitter.
971 return wxACC_FALSE;
972 }
973 // Let the framework handle the other cases.
974 return wxACC_NOT_IMPLEMENTED;
975}
976
977// Returns the description for this object or a child.
978wxAccStatus SplitterWindowAccessible::GetDescription(int childId, wxString* description)
979{
980 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
981 if (splitter)
982 {
983 if (splitter->IsSplit())
984 {
985 if (childId == 2)
986 {
987 * description = _("The splitter window sash.");
988 return wxACC_OK;
989 }
990 }
991 }
992 // Let the framework handle the other cases.
993 return wxACC_NOT_IMPLEMENTED;
994}
995
996// Returns help text for this object or a child, similar to tooltip text.
997wxAccStatus SplitterWindowAccessible::GetHelpText(int childId, wxString* helpText)
998{
999 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1000 if (splitter)
1001 {
1002 if (splitter->IsSplit())
1003 {
1004 if (childId == 2)
1005 {
1006 * helpText = _("The splitter window sash.");
1007 return wxACC_OK;
1008 }
1009 }
1010 }
1011 // Let the framework handle the other cases.
1012 return wxACC_NOT_IMPLEMENTED;
1013}
1014
1015// Returns the keyboard shortcut for this object or child.
1016// Return e.g. ALT+K
7d418908 1017wxAccStatus SplitterWindowAccessible::GetKeyboardShortcut(int childId, wxString* WXUNUSED(shortcut))
a37e4a07
JS
1018{
1019 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1020 if (splitter && splitter->IsSplit() && childId == 2)
1021 {
1022 // No keyboard shortcut for the splitter.
1023 return wxACC_FALSE;
1024 }
1025 // Let the framework handle the other cases.
1026 return wxACC_NOT_IMPLEMENTED;
1027}
1028
1029// Returns a role constant.
1030wxAccStatus SplitterWindowAccessible::GetRole(int childId, wxAccRole* role)
1031{
1032 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1033 if (splitter)
1034 {
1035 if (splitter->IsSplit())
1036 {
1037 if (childId == 2)
1038 {
1039 * role = wxROLE_SYSTEM_GRIP;
1040 return wxACC_OK;
1041 }
1042 }
1043 }
1044 // Let the framework handle the other cases.
1045 return wxACC_NOT_IMPLEMENTED;
1046}
1047
1048// Returns a state constant.
1049wxAccStatus SplitterWindowAccessible::GetState(int childId, long* state)
1050{
1051 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1052 if (splitter && splitter->IsSplit() && childId == 2)
1053 {
1054 // No particular state. Not sure what would be appropriate here.
1055 *state = wxACC_STATE_SYSTEM_UNAVAILABLE;
1056 return wxACC_OK;
1057 }
1058 // Let the framework handle the other cases.
1059 return wxACC_NOT_IMPLEMENTED;
1060}
1061
1062// Returns a localized string representing the value for the object
1063// or child.
1064wxAccStatus SplitterWindowAccessible::GetValue(int childId, wxString* strValue)
1065{
1066 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1067 if (splitter && splitter->IsSplit() && childId == 2)
1068 {
1069 // The sash position is the value.
1070 wxString pos;
1071 pos << splitter->GetSashPosition();
1072 *strValue = pos;
1073
1074 return wxACC_OK;
1075 }
1076 // Let the framework handle the other cases.
1077 return wxACC_NOT_IMPLEMENTED;
1078}
1079
1080// Selects the object or child.
7d418908 1081wxAccStatus SplitterWindowAccessible::Select(int childId, wxAccSelectionFlags WXUNUSED(selectFlags))
a37e4a07
JS
1082{
1083 wxSplitterWindow* splitter = wxDynamicCast(GetWindow(), wxSplitterWindow);
1084 if (splitter && splitter->IsSplit() && childId == 2)
1085 {
1086 // Can't select the sash.
1087 return wxACC_FALSE;
1088 }
1089 // Let the framework handle the other cases.
1090 return wxACC_NOT_IMPLEMENTED;
1091}
1092
1093// Gets the window with the keyboard focus.
1094// If childId is 0 and child is NULL, no object in
1095// this subhierarchy has the focus.
1096// If this object has the focus, child should be 'this'.
7d418908 1097wxAccStatus SplitterWindowAccessible::GetFocus(int* WXUNUSED(childId), wxAccessible** WXUNUSED(child))
a37e4a07
JS
1098{
1099 return wxACC_NOT_IMPLEMENTED;
1100}
1101
1102// Gets a variant representing the selected children
1103// of this object.
1104// Acceptable values:
5014bb3a 1105// - a null variant (IsNull() returns true)
a37e4a07
JS
1106// - a list variant (GetType() == wxT("list"))
1107// - an integer representing the selected child element,
1108// or 0 if this object is selected (GetType() == wxT("long"))
1109// - a "void*" pointer to a wxAccessible child object
7d418908 1110wxAccStatus SplitterWindowAccessible::GetSelections(wxVariant* WXUNUSED(selections))
a37e4a07
JS
1111{
1112 return wxACC_NOT_IMPLEMENTED;
1113}
1114
7d418908 1115#endif // wxUSE_ACCESSIBILITY