]> git.saurik.com Git - wxWidgets.git/blob - src/common/wincmn.cpp
221d6dbf2fce6374f4efe9a2dc24915f3cdc300a
[wxWidgets.git] / src / common / wincmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/window.cpp
3 // Purpose: common (to all ports) wxWindow functions
4 // Author: Julian Smart, Vadim Zeitlin
5 // Modified by:
6 // Created: 13/07/98
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWindows team
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "windowbase.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/string.h"
33 #include "wx/log.h"
34 #include "wx/intl.h"
35 #include "wx/frame.h"
36 #include "wx/defs.h"
37 #include "wx/window.h"
38 #include "wx/control.h"
39 #include "wx/checkbox.h"
40 #include "wx/radiobut.h"
41 #include "wx/statbox.h"
42 #include "wx/textctrl.h"
43 #include "wx/settings.h"
44 #include "wx/dialog.h"
45 #include "wx/msgdlg.h"
46 #include "wx/statusbr.h"
47 #include "wx/dcclient.h"
48 #endif //WX_PRECOMP
49
50 #if wxUSE_CONSTRAINTS
51 #include "wx/layout.h"
52 #endif // wxUSE_CONSTRAINTS
53
54 #include "wx/sizer.h"
55
56 #if wxUSE_DRAG_AND_DROP
57 #include "wx/dnd.h"
58 #endif // wxUSE_DRAG_AND_DROP
59
60 #if wxUSE_ACCESSIBILITY
61 #include "wx/access.h"
62 #endif
63
64 #if wxUSE_HELP
65 #include "wx/cshelp.h"
66 #endif // wxUSE_HELP
67
68 #if wxUSE_TOOLTIPS
69 #include "wx/tooltip.h"
70 #endif // wxUSE_TOOLTIPS
71
72 #if wxUSE_CARET
73 #include "wx/caret.h"
74 #endif // wxUSE_CARET
75
76 // ----------------------------------------------------------------------------
77 // static data
78 // ----------------------------------------------------------------------------
79
80 #if defined(__WXPM__)
81 int wxWindowBase::ms_lastControlId = 2000;
82 #else
83 int wxWindowBase::ms_lastControlId = -200;
84 #endif
85
86 IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
87
88 // ----------------------------------------------------------------------------
89 // event table
90 // ----------------------------------------------------------------------------
91
92 BEGIN_EVENT_TABLE(wxWindowBase, wxEvtHandler)
93 EVT_SYS_COLOUR_CHANGED(wxWindowBase::OnSysColourChanged)
94 EVT_INIT_DIALOG(wxWindowBase::OnInitDialog)
95 EVT_MIDDLE_DOWN(wxWindowBase::OnMiddleClick)
96
97 #if wxUSE_HELP
98 EVT_HELP(-1, wxWindowBase::OnHelp)
99 #endif // wxUSE_HELP
100
101 END_EVENT_TABLE()
102
103 // ============================================================================
104 // implementation of the common functionality of the wxWindow class
105 // ============================================================================
106
107 // ----------------------------------------------------------------------------
108 // initialization
109 // ----------------------------------------------------------------------------
110
111 // the default initialization
112 void wxWindowBase::InitBase()
113 {
114 // no window yet, no parent nor children
115 m_parent = (wxWindow *)NULL;
116 m_windowId = -1;
117 m_children.DeleteContents( FALSE ); // don't auto delete node data
118
119 // no constraints on the minimal window size
120 m_minWidth =
121 m_minHeight =
122 m_maxWidth =
123 m_maxHeight = -1;
124
125 // window is created enabled but it's not visible yet
126 m_isShown = FALSE;
127 m_isEnabled = TRUE;
128
129 // the default event handler is just this window
130 m_eventHandler = this;
131
132 #if wxUSE_VALIDATORS
133 // no validator
134 m_windowValidator = (wxValidator *) NULL;
135 #endif // wxUSE_VALIDATORS
136
137 // use the system default colours
138 m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
139 m_foregroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
140
141 // don't set the font here for wxMSW as we don't call WM_SETFONT here and
142 // so the font is *not* really set - but calls to SetFont() later won't do
143 // anything because m_font appears to be already set!
144 #ifndef __WXMSW__
145 m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
146 #endif // __WXMSW__
147
148 // the colours/fonts are default for now
149 m_hasBgCol =
150 m_hasFgCol =
151 m_hasFont = FALSE;
152
153 // no style bits
154 m_exStyle =
155 m_windowStyle = 0;
156
157 // an optimization for the event processing: checking this flag is much
158 // faster than using IsKindOf(CLASSINFO(wxWindow))
159 m_isWindow = TRUE;
160
161 #if wxUSE_CONSTRAINTS
162 // no constraints whatsoever
163 m_constraints = (wxLayoutConstraints *) NULL;
164 m_constraintsInvolvedIn = (wxWindowList *) NULL;
165 #endif // wxUSE_CONSTRAINTS
166
167 m_windowSizer = (wxSizer *) NULL;
168 m_containingSizer = (wxSizer *) NULL;
169 m_autoLayout = FALSE;
170
171 #if wxUSE_DRAG_AND_DROP
172 m_dropTarget = (wxDropTarget *)NULL;
173 #endif // wxUSE_DRAG_AND_DROP
174
175 #if wxUSE_TOOLTIPS
176 m_tooltip = (wxToolTip *)NULL;
177 #endif // wxUSE_TOOLTIPS
178
179 #if wxUSE_CARET
180 m_caret = (wxCaret *)NULL;
181 #endif // wxUSE_CARET
182
183 #if wxUSE_PALETTE
184 m_hasCustomPalette = FALSE;
185 #endif // wxUSE_PALETTE
186
187 #if wxUSE_ACCESSIBILITY
188 m_accessible = NULL;
189 #endif
190
191 m_virtualSize = wxDefaultSize;
192
193 m_minVirtualWidth =
194 m_minVirtualHeight =
195 m_maxVirtualWidth =
196 m_maxVirtualHeight = -1;
197
198 // Whether we're using the current theme for this window (wxGTK only for now)
199 m_themeEnabled = FALSE;
200 }
201
202 // common part of window creation process
203 bool wxWindowBase::CreateBase(wxWindowBase *parent,
204 wxWindowID id,
205 const wxPoint& WXUNUSED(pos),
206 const wxSize& WXUNUSED(size),
207 long style,
208 const wxValidator& validator,
209 const wxString& name)
210 {
211 // m_isWindow is set to TRUE in wxWindowBase::Init() as well as many other
212 // member variables - check that it has been called (will catch the case
213 // when a new ctor is added which doesn't call InitWindow)
214 wxASSERT_MSG( m_isWindow, wxT("Init() must have been called before!") );
215
216 #if wxUSE_STATBOX
217 // wxGTK doesn't allow to create controls with static box as the parent so
218 // this will result in a crash when the program is ported to wxGTK so warn
219 // the user about it
220
221 // if you get this assert, the correct solution is to create the controls
222 // as siblings of the static box
223 wxASSERT_MSG( !parent || !wxDynamicCast(parent, wxStaticBox),
224 _T("wxStaticBox can't be used as a window parent!") );
225 #endif // wxUSE_STATBOX
226
227 // generate a new id if the user doesn't care about it
228 m_windowId = id == -1 ? NewControlId() : id;
229
230 SetName(name);
231 SetWindowStyleFlag(style);
232 SetParent(parent);
233
234 #if wxUSE_VALIDATORS
235 SetValidator(validator);
236 #endif // wxUSE_VALIDATORS
237
238 // if the parent window has wxWS_EX_VALIDATE_RECURSIVELY set, we want to
239 // have it too - like this it's possible to set it only in the top level
240 // dialog/frame and all children will inherit it by defult
241 if ( parent && (parent->GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) )
242 {
243 SetExtraStyle(GetExtraStyle() | wxWS_EX_VALIDATE_RECURSIVELY);
244 }
245
246 return TRUE;
247 }
248
249 // ----------------------------------------------------------------------------
250 // destruction
251 // ----------------------------------------------------------------------------
252
253 // common clean up
254 wxWindowBase::~wxWindowBase()
255 {
256 wxASSERT_MSG( GetCapture() != this, wxT("attempt to destroy window with mouse capture") );
257
258 // FIXME if these 2 cases result from programming errors in the user code
259 // we should probably assert here instead of silently fixing them
260
261 // Just in case the window has been Closed, but we're then deleting
262 // immediately: don't leave dangling pointers.
263 wxPendingDelete.DeleteObject(this);
264
265 // Just in case we've loaded a top-level window via LoadNativeDialog but
266 // we weren't a dialog class
267 wxTopLevelWindows.DeleteObject(this);
268
269 wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );
270
271 #if wxUSE_CARET
272 if ( m_caret )
273 delete m_caret;
274 #endif // wxUSE_CARET
275
276 #if wxUSE_VALIDATORS
277 if ( m_windowValidator )
278 delete m_windowValidator;
279 #endif // wxUSE_VALIDATORS
280
281 #if wxUSE_CONSTRAINTS
282 // Have to delete constraints/sizer FIRST otherwise sizers may try to look
283 // at deleted windows as they delete themselves.
284 DeleteRelatedConstraints();
285
286 if ( m_constraints )
287 {
288 // This removes any dangling pointers to this window in other windows'
289 // constraintsInvolvedIn lists.
290 UnsetConstraints(m_constraints);
291 delete m_constraints;
292 m_constraints = NULL;
293 }
294
295 #endif // wxUSE_CONSTRAINTS
296
297 if ( m_containingSizer )
298 m_containingSizer->Detach( (wxWindow*)this );
299
300 if ( m_windowSizer )
301 delete m_windowSizer;
302
303 #if wxUSE_DRAG_AND_DROP
304 if ( m_dropTarget )
305 delete m_dropTarget;
306 #endif // wxUSE_DRAG_AND_DROP
307
308 #if wxUSE_TOOLTIPS
309 if ( m_tooltip )
310 delete m_tooltip;
311 #endif // wxUSE_TOOLTIPS
312
313 #if wxUSE_ACCESSIBILITY
314 if ( m_accessible )
315 delete m_accessible;
316 #endif
317
318 // reset the dangling pointer our parent window may keep to us
319 if ( m_parent && m_parent->GetDefaultItem() == this )
320 {
321 m_parent->SetDefaultItem(NULL);
322 }
323 }
324
325 bool wxWindowBase::Destroy()
326 {
327 delete this;
328
329 return TRUE;
330 }
331
332 bool wxWindowBase::Close(bool force)
333 {
334 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
335 event.SetEventObject(this);
336 #if WXWIN_COMPATIBILITY
337 event.SetForce(force);
338 #endif // WXWIN_COMPATIBILITY
339 event.SetCanVeto(!force);
340
341 // return FALSE if window wasn't closed because the application vetoed the
342 // close event
343 return GetEventHandler()->ProcessEvent(event) && !event.GetVeto();
344 }
345
346 bool wxWindowBase::DestroyChildren()
347 {
348 wxWindowList::Node *node;
349 for ( ;; )
350 {
351 // we iterate until the list becomes empty
352 node = GetChildren().GetFirst();
353 if ( !node )
354 break;
355
356 wxWindow *child = node->GetData();
357
358 wxASSERT_MSG( child, wxT("children list contains empty nodes") );
359
360 child->Show(FALSE);
361 delete child;
362
363 wxASSERT_MSG( !GetChildren().Find(child),
364 wxT("child didn't remove itself using RemoveChild()") );
365 }
366
367 return TRUE;
368 }
369
370 // ----------------------------------------------------------------------------
371 // size/position related methods
372 // ----------------------------------------------------------------------------
373
374 // centre the window with respect to its parent in either (or both) directions
375 void wxWindowBase::Centre(int direction)
376 {
377 // the position/size of the parent window or of the entire screen
378 wxPoint posParent;
379 int widthParent, heightParent;
380
381 wxWindow *parent = NULL;
382
383 if ( !(direction & wxCENTRE_ON_SCREEN) )
384 {
385 // find the parent to centre this window on: it should be the
386 // immediate parent for the controls but the top level parent for the
387 // top level windows (like dialogs)
388 parent = GetParent();
389 if ( IsTopLevel() )
390 {
391 while ( parent && !parent->IsTopLevel() )
392 {
393 parent = parent->GetParent();
394 }
395 }
396
397 // there is no wxTopLevelWindow under wxMotif yet
398 #ifndef __WXMOTIF__
399 // we shouldn't center the dialog on the iconized window: under
400 // Windows, for example, this places it completely off the screen
401 if ( parent )
402 {
403 wxTopLevelWindow *winTop = wxDynamicCast(parent, wxTopLevelWindow);
404 if ( winTop && winTop->IsIconized() )
405 {
406 parent = NULL;
407 }
408 }
409 #endif // __WXMOTIF__
410
411 // did we find the parent?
412 if ( !parent )
413 {
414 // no other choice
415 direction |= wxCENTRE_ON_SCREEN;
416 }
417 }
418
419 if ( direction & wxCENTRE_ON_SCREEN )
420 {
421 // centre with respect to the whole screen
422 wxDisplaySize(&widthParent, &heightParent);
423 }
424 else
425 {
426 if ( IsTopLevel() )
427 {
428 // centre on the parent
429 parent->GetSize(&widthParent, &heightParent);
430
431 // adjust to the parents position
432 posParent = parent->GetPosition();
433 }
434 else
435 {
436 // centre inside the parents client rectangle
437 parent->GetClientSize(&widthParent, &heightParent);
438 }
439 }
440
441 int width, height;
442 GetSize(&width, &height);
443
444 int xNew = -1,
445 yNew = -1;
446
447 if ( direction & wxHORIZONTAL )
448 xNew = (widthParent - width)/2;
449
450 if ( direction & wxVERTICAL )
451 yNew = (heightParent - height)/2;
452
453 xNew += posParent.x;
454 yNew += posParent.y;
455
456 // Base size of the visible dimensions of the display
457 // to take into account the taskbar
458 wxRect rect = wxGetClientDisplayRect();
459 wxSize size (rect.width,rect.height);
460
461 // NB: in wxMSW, negative position may not neccessary mean "out of screen",
462 // but it may mean that the window is placed on other than the main
463 // display. Therefore we only make sure centered window is on the main display
464 // if the parent is at least partially present here.
465 if (posParent.x + widthParent >= 0) // if parent is (partially) on the main display
466 {
467 if (xNew < 0)
468 xNew = 0;
469 else if (xNew+width > size.x)
470 xNew = size.x-width-1;
471 }
472 if (posParent.y + heightParent >= 0) // if parent is (partially) on the main display
473 {
474 if (yNew+height > size.y)
475 yNew = size.y-height-1;
476
477 // Make certain that the title bar is initially visible
478 // always, even if this would push the bottom of the
479 // dialog of the visible area of the display
480 if (yNew < 0)
481 yNew = 0;
482 }
483
484 // move the window to this position (keeping the old size but using
485 // SetSize() and not Move() to allow xNew and/or yNew to be -1)
486 SetSize(xNew, yNew, width, height, wxSIZE_ALLOW_MINUS_ONE);
487 }
488
489 // fits the window around the children
490 void wxWindowBase::Fit()
491 {
492 if ( GetChildren().GetCount() > 0 )
493 {
494 SetClientSize(DoGetBestSize());
495 }
496 //else: do nothing if we have no children
497 }
498
499 // fits virtual size (ie. scrolled area etc.) around children
500 void wxWindowBase::FitInside()
501 {
502 if ( GetChildren().GetCount() > 0 )
503 {
504 SetVirtualSize( GetBestVirtualSize() );
505 }
506 }
507
508 // return the size best suited for the current window
509 wxSize wxWindowBase::DoGetBestSize() const
510 {
511 if ( m_windowSizer )
512 {
513 return m_windowSizer->GetMinSize();
514 }
515 #if wxUSE_CONSTRAINTS
516 else if ( m_constraints )
517 {
518 wxConstCast(this, wxWindowBase)->SatisfyConstraints();
519
520 // our minimal acceptable size is such that all our windows fit inside
521 int maxX = 0,
522 maxY = 0;
523
524 for ( wxWindowList::Node *node = GetChildren().GetFirst();
525 node;
526 node = node->GetNext() )
527 {
528 wxLayoutConstraints *c = node->GetData()->GetConstraints();
529 if ( !c )
530 {
531 // it's not normal that we have an unconstrained child, but
532 // what can we do about it?
533 continue;
534 }
535
536 int x = c->right.GetValue(),
537 y = c->bottom.GetValue();
538
539 if ( x > maxX )
540 maxX = x;
541
542 if ( y > maxY )
543 maxY = y;
544
545 // TODO: we must calculate the overlaps somehow, otherwise we
546 // will never return a size bigger than the current one :-(
547 }
548
549 return wxSize(maxX, maxY);
550 }
551 #endif // wxUSE_CONSTRAINTS
552 else if ( GetChildren().GetCount() > 0 )
553 {
554 // our minimal acceptable size is such that all our windows fit inside
555 int maxX = 0,
556 maxY = 0;
557
558 for ( wxWindowList::Node *node = GetChildren().GetFirst();
559 node;
560 node = node->GetNext() )
561 {
562 wxWindow *win = node->GetData();
563 if ( win->IsTopLevel()
564 #if wxUSE_STATUSBAR
565 || wxDynamicCast(win, wxStatusBar)
566 #endif // wxUSE_STATUSBAR
567 )
568 {
569 // dialogs and frames lie in different top level windows -
570 // don't deal with them here; as for the status bars, they
571 // don't lie in the client area at all
572 continue;
573 }
574
575 int wx, wy, ww, wh;
576 win->GetPosition(&wx, &wy);
577
578 // if the window hadn't been positioned yet, assume that it is in
579 // the origin
580 if ( wx == -1 )
581 wx = 0;
582 if ( wy == -1 )
583 wy = 0;
584
585 win->GetSize(&ww, &wh);
586 if ( wx + ww > maxX )
587 maxX = wx + ww;
588 if ( wy + wh > maxY )
589 maxY = wy + wh;
590 }
591
592 // for compatibility with the old versions and because it really looks
593 // slightly more pretty like this, add a pad
594 maxX += 7;
595 maxY += 14;
596
597 return wxSize(maxX, maxY);
598 }
599 else
600 {
601 // for a generic window there is no natural best size - just use the
602 // current one
603 return GetSize();
604 }
605 }
606
607 // by default the origin is not shifted
608 wxPoint wxWindowBase::GetClientAreaOrigin() const
609 {
610 return wxPoint(0, 0);
611 }
612
613 // set the min/max size of the window
614 void wxWindowBase::SetSizeHints(int minW, int minH,
615 int maxW, int maxH,
616 int WXUNUSED(incW), int WXUNUSED(incH))
617 {
618 m_minWidth = minW;
619 m_maxWidth = maxW;
620 m_minHeight = minH;
621 m_maxHeight = maxH;
622 }
623
624 void wxWindowBase::SetVirtualSizeHints( int minW, int minH,
625 int maxW, int maxH )
626 {
627 m_minVirtualWidth = minW;
628 m_maxVirtualWidth = maxW;
629 m_minVirtualHeight = minH;
630 m_maxVirtualHeight = maxH;
631 }
632
633 void wxWindowBase::DoSetVirtualSize( int x, int y )
634 {
635 if ( m_minVirtualWidth != -1 && m_minVirtualWidth > x )
636 x = m_minVirtualWidth;
637 if ( m_maxVirtualWidth != -1 && m_maxVirtualWidth < x )
638 x = m_maxVirtualWidth;
639 if ( m_minVirtualHeight != -1 && m_minVirtualHeight > y )
640 y = m_minVirtualHeight;
641 if ( m_maxVirtualHeight != -1 && m_maxVirtualHeight < y )
642 y = m_maxVirtualHeight;
643
644 m_virtualSize = wxSize(x, y);
645 }
646
647 wxSize wxWindowBase::DoGetVirtualSize() const
648 {
649 wxSize s( GetClientSize() );
650
651 return wxSize( wxMax( m_virtualSize.GetWidth(), s.GetWidth() ),
652 wxMax( m_virtualSize.GetHeight(), s.GetHeight() ) );
653 }
654
655 // ----------------------------------------------------------------------------
656 // show/hide/enable/disable the window
657 // ----------------------------------------------------------------------------
658
659 bool wxWindowBase::Show(bool show)
660 {
661 if ( show != m_isShown )
662 {
663 m_isShown = show;
664
665 return TRUE;
666 }
667 else
668 {
669 return FALSE;
670 }
671 }
672
673 bool wxWindowBase::Enable(bool enable)
674 {
675 if ( enable != m_isEnabled )
676 {
677 m_isEnabled = enable;
678
679 return TRUE;
680 }
681 else
682 {
683 return FALSE;
684 }
685 }
686 // ----------------------------------------------------------------------------
687 // RTTI
688 // ----------------------------------------------------------------------------
689
690 bool wxWindowBase::IsTopLevel() const
691 {
692 return FALSE;
693 }
694
695 // ----------------------------------------------------------------------------
696 // reparenting the window
697 // ----------------------------------------------------------------------------
698
699 void wxWindowBase::AddChild(wxWindowBase *child)
700 {
701 wxCHECK_RET( child, wxT("can't add a NULL child") );
702
703 // this should never happen and it will lead to a crash later if it does
704 // because RemoveChild() will remove only one node from the children list
705 // and the other(s) one(s) will be left with dangling pointers in them
706 wxASSERT_MSG( !GetChildren().Find(child), _T("AddChild() called twice") );
707
708 GetChildren().Append(child);
709 child->SetParent(this);
710 }
711
712 void wxWindowBase::RemoveChild(wxWindowBase *child)
713 {
714 wxCHECK_RET( child, wxT("can't remove a NULL child") );
715
716 GetChildren().DeleteObject(child);
717 child->SetParent((wxWindow *)NULL);
718 }
719
720 bool wxWindowBase::Reparent(wxWindowBase *newParent)
721 {
722 wxWindow *oldParent = GetParent();
723 if ( newParent == oldParent )
724 {
725 // nothing done
726 return FALSE;
727 }
728
729 // unlink this window from the existing parent.
730 if ( oldParent )
731 {
732 oldParent->RemoveChild(this);
733 }
734 else
735 {
736 wxTopLevelWindows.DeleteObject(this);
737 }
738
739 // add it to the new one
740 if ( newParent )
741 {
742 newParent->AddChild(this);
743 }
744 else
745 {
746 wxTopLevelWindows.Append(this);
747 }
748
749 return TRUE;
750 }
751
752 // ----------------------------------------------------------------------------
753 // event handler stuff
754 // ----------------------------------------------------------------------------
755
756 void wxWindowBase::PushEventHandler(wxEvtHandler *handler)
757 {
758 wxEvtHandler *handlerOld = GetEventHandler();
759
760 handler->SetNextHandler(handlerOld);
761
762 if ( handlerOld )
763 GetEventHandler()->SetPreviousHandler(handler);
764
765 SetEventHandler(handler);
766 }
767
768 wxEvtHandler *wxWindowBase::PopEventHandler(bool deleteHandler)
769 {
770 wxEvtHandler *handlerA = GetEventHandler();
771 if ( handlerA )
772 {
773 wxEvtHandler *handlerB = handlerA->GetNextHandler();
774 handlerA->SetNextHandler((wxEvtHandler *)NULL);
775
776 if ( handlerB )
777 handlerB->SetPreviousHandler((wxEvtHandler *)NULL);
778 SetEventHandler(handlerB);
779
780 if ( deleteHandler )
781 {
782 delete handlerA;
783 handlerA = (wxEvtHandler *)NULL;
784 }
785 }
786
787 return handlerA;
788 }
789
790 bool wxWindowBase::RemoveEventHandler(wxEvtHandler *handler)
791 {
792 wxCHECK_MSG( handler, FALSE, _T("RemoveEventHandler(NULL) called") );
793
794 wxEvtHandler *handlerPrev = NULL,
795 *handlerCur = GetEventHandler();
796 while ( handlerCur )
797 {
798 wxEvtHandler *handlerNext = handlerCur->GetNextHandler();
799
800 if ( handlerCur == handler )
801 {
802 if ( handlerPrev )
803 {
804 handlerPrev->SetNextHandler(handlerNext);
805 }
806 else
807 {
808 SetEventHandler(handlerNext);
809 }
810
811 if ( handlerNext )
812 {
813 handlerNext->SetPreviousHandler ( handlerPrev );
814 }
815 handler->SetNextHandler(NULL);
816
817 return TRUE;
818 }
819
820 handlerPrev = handlerCur;
821 handlerCur = handlerNext;
822 }
823
824 wxFAIL_MSG( _T("where has the event handler gone?") );
825
826 return FALSE;
827 }
828
829 // ----------------------------------------------------------------------------
830 // cursors, fonts &c
831 // ----------------------------------------------------------------------------
832
833 bool wxWindowBase::SetBackgroundColour( const wxColour &colour )
834 {
835 if ( !colour.Ok() || (colour == m_backgroundColour) )
836 return FALSE;
837
838 m_backgroundColour = colour;
839
840 m_hasBgCol = TRUE;
841
842 return TRUE;
843 }
844
845 bool wxWindowBase::SetForegroundColour( const wxColour &colour )
846 {
847 if ( !colour.Ok() || (colour == m_foregroundColour) )
848 return FALSE;
849
850 m_foregroundColour = colour;
851
852 m_hasFgCol = TRUE;
853
854 return TRUE;
855 }
856
857 bool wxWindowBase::SetCursor(const wxCursor& cursor)
858 {
859 // setting an invalid cursor is ok, it means that we don't have any special
860 // cursor
861 if ( m_cursor == cursor )
862 {
863 // no change
864 return FALSE;
865 }
866
867 m_cursor = cursor;
868
869 return TRUE;
870 }
871
872 bool wxWindowBase::SetFont(const wxFont& font)
873 {
874 // don't try to set invalid font, always fall back to the default
875 const wxFont& fontOk = font.Ok() ? font : *wxSWISS_FONT;
876
877 if ( fontOk == m_font )
878 {
879 // no change
880 return FALSE;
881 }
882
883 m_font = fontOk;
884
885 m_hasFont = TRUE;
886
887 return TRUE;
888 }
889
890 #if wxUSE_PALETTE
891
892 void wxWindowBase::SetPalette(const wxPalette& pal)
893 {
894 m_hasCustomPalette = TRUE;
895 m_palette = pal;
896
897 // VZ: can anyone explain me what do we do here?
898 wxWindowDC d((wxWindow *) this);
899 d.SetPalette(pal);
900 }
901
902 wxWindow *wxWindowBase::GetAncestorWithCustomPalette() const
903 {
904 wxWindow *win = (wxWindow *)this;
905 while ( win && !win->HasCustomPalette() )
906 {
907 win = win->GetParent();
908 }
909
910 return win;
911 }
912
913 #endif // wxUSE_PALETTE
914
915 #if wxUSE_CARET
916 void wxWindowBase::SetCaret(wxCaret *caret)
917 {
918 if ( m_caret )
919 {
920 delete m_caret;
921 }
922
923 m_caret = caret;
924
925 if ( m_caret )
926 {
927 wxASSERT_MSG( m_caret->GetWindow() == this,
928 wxT("caret should be created associated to this window") );
929 }
930 }
931 #endif // wxUSE_CARET
932
933 #if wxUSE_VALIDATORS
934 // ----------------------------------------------------------------------------
935 // validators
936 // ----------------------------------------------------------------------------
937
938 void wxWindowBase::SetValidator(const wxValidator& validator)
939 {
940 if ( m_windowValidator )
941 delete m_windowValidator;
942
943 m_windowValidator = (wxValidator *)validator.Clone();
944
945 if ( m_windowValidator )
946 m_windowValidator->SetWindow(this) ;
947 }
948 #endif // wxUSE_VALIDATORS
949
950 // ----------------------------------------------------------------------------
951 // update region stuff
952 // ----------------------------------------------------------------------------
953
954 wxRect wxWindowBase::GetUpdateClientRect() const
955 {
956 wxRegion rgnUpdate = GetUpdateRegion();
957 rgnUpdate.Intersect(GetClientRect());
958 wxRect rectUpdate = rgnUpdate.GetBox();
959 wxPoint ptOrigin = GetClientAreaOrigin();
960 rectUpdate.x -= ptOrigin.x;
961 rectUpdate.y -= ptOrigin.y;
962
963 return rectUpdate;
964 }
965
966 bool wxWindowBase::IsExposed(int x, int y) const
967 {
968 return m_updateRegion.Contains(x, y) != wxOutRegion;
969 }
970
971 bool wxWindowBase::IsExposed(int x, int y, int w, int h) const
972 {
973 return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
974 }
975
976 // ----------------------------------------------------------------------------
977 // find child window by id or name
978 // ----------------------------------------------------------------------------
979
980 wxWindow *wxWindowBase::FindWindow( long id )
981 {
982 if ( id == m_windowId )
983 return (wxWindow *)this;
984
985 wxWindowBase *res = (wxWindow *)NULL;
986 wxWindowList::Node *node;
987 for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
988 {
989 wxWindowBase *child = node->GetData();
990 res = child->FindWindow( id );
991 }
992
993 return (wxWindow *)res;
994 }
995
996 wxWindow *wxWindowBase::FindWindow( const wxString& name )
997 {
998 if ( name == m_windowName )
999 return (wxWindow *)this;
1000
1001 wxWindowBase *res = (wxWindow *)NULL;
1002 wxWindowList::Node *node;
1003 for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
1004 {
1005 wxWindow *child = node->GetData();
1006 res = child->FindWindow(name);
1007 }
1008
1009 return (wxWindow *)res;
1010 }
1011
1012
1013 // find any window by id or name or label: If parent is non-NULL, look through
1014 // children for a label or title matching the specified string. If NULL, look
1015 // through all top-level windows.
1016 //
1017 // to avoid duplicating code we reuse the same helper function but with
1018 // different comparators
1019
1020 typedef bool (*wxFindWindowCmp)(const wxWindow *win,
1021 const wxString& label, long id);
1022
1023 static
1024 bool wxFindWindowCmpLabels(const wxWindow *win, const wxString& label,
1025 long WXUNUSED(id))
1026 {
1027 return win->GetLabel() == label;
1028 }
1029
1030 static
1031 bool wxFindWindowCmpNames(const wxWindow *win, const wxString& label,
1032 long WXUNUSED(id))
1033 {
1034 return win->GetName() == label;
1035 }
1036
1037 static
1038 bool wxFindWindowCmpIds(const wxWindow *win, const wxString& WXUNUSED(label),
1039 long id)
1040 {
1041 return win->GetId() == id;
1042 }
1043
1044 // recursive helper for the FindWindowByXXX() functions
1045 static
1046 wxWindow *wxFindWindowRecursively(const wxWindow *parent,
1047 const wxString& label,
1048 long id,
1049 wxFindWindowCmp cmp)
1050 {
1051 if ( parent )
1052 {
1053 // see if this is the one we're looking for
1054 if ( (*cmp)(parent, label, id) )
1055 return (wxWindow *)parent;
1056
1057 // It wasn't, so check all its children
1058 for ( wxWindowList::Node * node = parent->GetChildren().GetFirst();
1059 node;
1060 node = node->GetNext() )
1061 {
1062 // recursively check each child
1063 wxWindow *win = (wxWindow *)node->GetData();
1064 wxWindow *retwin = wxFindWindowRecursively(win, label, id, cmp);
1065 if (retwin)
1066 return retwin;
1067 }
1068 }
1069
1070 // Not found
1071 return NULL;
1072 }
1073
1074 // helper for FindWindowByXXX()
1075 static
1076 wxWindow *wxFindWindowHelper(const wxWindow *parent,
1077 const wxString& label,
1078 long id,
1079 wxFindWindowCmp cmp)
1080 {
1081 if ( parent )
1082 {
1083 // just check parent and all its children
1084 return wxFindWindowRecursively(parent, label, id, cmp);
1085 }
1086
1087 // start at very top of wx's windows
1088 for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst();
1089 node;
1090 node = node->GetNext() )
1091 {
1092 // recursively check each window & its children
1093 wxWindow *win = node->GetData();
1094 wxWindow *retwin = wxFindWindowRecursively(win, label, id, cmp);
1095 if (retwin)
1096 return retwin;
1097 }
1098
1099 return NULL;
1100 }
1101
1102 /* static */
1103 wxWindow *
1104 wxWindowBase::FindWindowByLabel(const wxString& title, const wxWindow *parent)
1105 {
1106 return wxFindWindowHelper(parent, title, 0, wxFindWindowCmpLabels);
1107 }
1108
1109 /* static */
1110 wxWindow *
1111 wxWindowBase::FindWindowByName(const wxString& title, const wxWindow *parent)
1112 {
1113 wxWindow *win = wxFindWindowHelper(parent, title, 0, wxFindWindowCmpNames);
1114
1115 if ( !win )
1116 {
1117 // fall back to the label
1118 win = FindWindowByLabel(title, parent);
1119 }
1120
1121 return win;
1122 }
1123
1124 /* static */
1125 wxWindow *
1126 wxWindowBase::FindWindowById( long id, const wxWindow* parent )
1127 {
1128 return wxFindWindowHelper(parent, _T(""), id, wxFindWindowCmpIds);
1129 }
1130
1131 // ----------------------------------------------------------------------------
1132 // dialog oriented functions
1133 // ----------------------------------------------------------------------------
1134
1135 void wxWindowBase::MakeModal(bool modal)
1136 {
1137 // Disable all other windows
1138 if ( IsTopLevel() )
1139 {
1140 wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
1141 while (node)
1142 {
1143 wxWindow *win = node->GetData();
1144 if (win != this)
1145 win->Enable(!modal);
1146
1147 node = node->GetNext();
1148 }
1149 }
1150 }
1151
1152 bool wxWindowBase::Validate()
1153 {
1154 #if wxUSE_VALIDATORS
1155 bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
1156
1157 wxWindowList::Node *node;
1158 for ( node = m_children.GetFirst(); node; node = node->GetNext() )
1159 {
1160 wxWindowBase *child = node->GetData();
1161 wxValidator *validator = child->GetValidator();
1162 if ( validator && !validator->Validate((wxWindow *)this) )
1163 {
1164 return FALSE;
1165 }
1166
1167 if ( recurse && !child->Validate() )
1168 {
1169 return FALSE;
1170 }
1171 }
1172 #endif // wxUSE_VALIDATORS
1173
1174 return TRUE;
1175 }
1176
1177 bool wxWindowBase::TransferDataToWindow()
1178 {
1179 #if wxUSE_VALIDATORS
1180 bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
1181
1182 wxWindowList::Node *node;
1183 for ( node = m_children.GetFirst(); node; node = node->GetNext() )
1184 {
1185 wxWindowBase *child = node->GetData();
1186 wxValidator *validator = child->GetValidator();
1187 if ( validator && !validator->TransferToWindow() )
1188 {
1189 wxLogWarning(_("Could not transfer data to window"));
1190 #if wxUSE_LOG
1191 wxLog::FlushActive();
1192 #endif // wxUSE_LOG
1193
1194 return FALSE;
1195 }
1196
1197 if ( recurse )
1198 {
1199 if ( !child->TransferDataToWindow() )
1200 {
1201 // warning already given
1202 return FALSE;
1203 }
1204 }
1205 }
1206 #endif // wxUSE_VALIDATORS
1207
1208 return TRUE;
1209 }
1210
1211 bool wxWindowBase::TransferDataFromWindow()
1212 {
1213 #if wxUSE_VALIDATORS
1214 bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
1215
1216 wxWindowList::Node *node;
1217 for ( node = m_children.GetFirst(); node; node = node->GetNext() )
1218 {
1219 wxWindow *child = node->GetData();
1220 wxValidator *validator = child->GetValidator();
1221 if ( validator && !validator->TransferFromWindow() )
1222 {
1223 // nop warning here because the application is supposed to give
1224 // one itself - we don't know here what might have gone wrongly
1225
1226 return FALSE;
1227 }
1228
1229 if ( recurse )
1230 {
1231 if ( !child->TransferDataFromWindow() )
1232 {
1233 // warning already given
1234 return FALSE;
1235 }
1236 }
1237 }
1238 #endif // wxUSE_VALIDATORS
1239
1240 return TRUE;
1241 }
1242
1243 void wxWindowBase::InitDialog()
1244 {
1245 wxInitDialogEvent event(GetId());
1246 event.SetEventObject( this );
1247 GetEventHandler()->ProcessEvent(event);
1248 }
1249
1250 // ----------------------------------------------------------------------------
1251 // context-sensitive help support
1252 // ----------------------------------------------------------------------------
1253
1254 #if wxUSE_HELP
1255
1256 // associate this help text with this window
1257 void wxWindowBase::SetHelpText(const wxString& text)
1258 {
1259 wxHelpProvider *helpProvider = wxHelpProvider::Get();
1260 if ( helpProvider )
1261 {
1262 helpProvider->AddHelp(this, text);
1263 }
1264 }
1265
1266 // associate this help text with all windows with the same id as this
1267 // one
1268 void wxWindowBase::SetHelpTextForId(const wxString& text)
1269 {
1270 wxHelpProvider *helpProvider = wxHelpProvider::Get();
1271 if ( helpProvider )
1272 {
1273 helpProvider->AddHelp(GetId(), text);
1274 }
1275 }
1276
1277 // get the help string associated with this window (may be empty)
1278 wxString wxWindowBase::GetHelpText() const
1279 {
1280 wxString text;
1281 wxHelpProvider *helpProvider = wxHelpProvider::Get();
1282 if ( helpProvider )
1283 {
1284 text = helpProvider->GetHelp(this);
1285 }
1286
1287 return text;
1288 }
1289
1290 // show help for this window
1291 void wxWindowBase::OnHelp(wxHelpEvent& event)
1292 {
1293 wxHelpProvider *helpProvider = wxHelpProvider::Get();
1294 if ( helpProvider )
1295 {
1296 if ( helpProvider->ShowHelp(this) )
1297 {
1298 // skip the event.Skip() below
1299 return;
1300 }
1301 }
1302
1303 event.Skip();
1304 }
1305
1306 #endif // wxUSE_HELP
1307
1308 // ----------------------------------------------------------------------------
1309 // tooltipsroot.Replace("\\", "/");
1310 // ----------------------------------------------------------------------------
1311
1312 #if wxUSE_TOOLTIPS
1313
1314 void wxWindowBase::SetToolTip( const wxString &tip )
1315 {
1316 // don't create the new tooltip if we already have one
1317 if ( m_tooltip )
1318 {
1319 m_tooltip->SetTip( tip );
1320 }
1321 else
1322 {
1323 SetToolTip( new wxToolTip( tip ) );
1324 }
1325
1326 // setting empty tooltip text does not remove the tooltip any more - use
1327 // SetToolTip((wxToolTip *)NULL) for this
1328 }
1329
1330 void wxWindowBase::DoSetToolTip(wxToolTip *tooltip)
1331 {
1332 if ( m_tooltip )
1333 delete m_tooltip;
1334
1335 m_tooltip = tooltip;
1336 }
1337
1338 #endif // wxUSE_TOOLTIPS
1339
1340 // ----------------------------------------------------------------------------
1341 // constraints and sizers
1342 // ----------------------------------------------------------------------------
1343
1344 #if wxUSE_CONSTRAINTS
1345
1346 void wxWindowBase::SetConstraints( wxLayoutConstraints *constraints )
1347 {
1348 if ( m_constraints )
1349 {
1350 UnsetConstraints(m_constraints);
1351 delete m_constraints;
1352 }
1353 m_constraints = constraints;
1354 if ( m_constraints )
1355 {
1356 // Make sure other windows know they're part of a 'meaningful relationship'
1357 if ( m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this) )
1358 m_constraints->left.GetOtherWindow()->AddConstraintReference(this);
1359 if ( m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this) )
1360 m_constraints->top.GetOtherWindow()->AddConstraintReference(this);
1361 if ( m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this) )
1362 m_constraints->right.GetOtherWindow()->AddConstraintReference(this);
1363 if ( m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this) )
1364 m_constraints->bottom.GetOtherWindow()->AddConstraintReference(this);
1365 if ( m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this) )
1366 m_constraints->width.GetOtherWindow()->AddConstraintReference(this);
1367 if ( m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this) )
1368 m_constraints->height.GetOtherWindow()->AddConstraintReference(this);
1369 if ( m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this) )
1370 m_constraints->centreX.GetOtherWindow()->AddConstraintReference(this);
1371 if ( m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this) )
1372 m_constraints->centreY.GetOtherWindow()->AddConstraintReference(this);
1373 }
1374 }
1375
1376 // This removes any dangling pointers to this window in other windows'
1377 // constraintsInvolvedIn lists.
1378 void wxWindowBase::UnsetConstraints(wxLayoutConstraints *c)
1379 {
1380 if ( c )
1381 {
1382 if ( c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this) )
1383 c->left.GetOtherWindow()->RemoveConstraintReference(this);
1384 if ( c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this) )
1385 c->top.GetOtherWindow()->RemoveConstraintReference(this);
1386 if ( c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this) )
1387 c->right.GetOtherWindow()->RemoveConstraintReference(this);
1388 if ( c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this) )
1389 c->bottom.GetOtherWindow()->RemoveConstraintReference(this);
1390 if ( c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this) )
1391 c->width.GetOtherWindow()->RemoveConstraintReference(this);
1392 if ( c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this) )
1393 c->height.GetOtherWindow()->RemoveConstraintReference(this);
1394 if ( c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this) )
1395 c->centreX.GetOtherWindow()->RemoveConstraintReference(this);
1396 if ( c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this) )
1397 c->centreY.GetOtherWindow()->RemoveConstraintReference(this);
1398 }
1399 }
1400
1401 // Back-pointer to other windows we're involved with, so if we delete this
1402 // window, we must delete any constraints we're involved with.
1403 void wxWindowBase::AddConstraintReference(wxWindowBase *otherWin)
1404 {
1405 if ( !m_constraintsInvolvedIn )
1406 m_constraintsInvolvedIn = new wxWindowList;
1407 if ( !m_constraintsInvolvedIn->Find(otherWin) )
1408 m_constraintsInvolvedIn->Append(otherWin);
1409 }
1410
1411 // REMOVE back-pointer to other windows we're involved with.
1412 void wxWindowBase::RemoveConstraintReference(wxWindowBase *otherWin)
1413 {
1414 if ( m_constraintsInvolvedIn )
1415 m_constraintsInvolvedIn->DeleteObject(otherWin);
1416 }
1417
1418 // Reset any constraints that mention this window
1419 void wxWindowBase::DeleteRelatedConstraints()
1420 {
1421 if ( m_constraintsInvolvedIn )
1422 {
1423 wxWindowList::Node *node = m_constraintsInvolvedIn->GetFirst();
1424 while (node)
1425 {
1426 wxWindow *win = node->GetData();
1427 wxLayoutConstraints *constr = win->GetConstraints();
1428
1429 // Reset any constraints involving this window
1430 if ( constr )
1431 {
1432 constr->left.ResetIfWin(this);
1433 constr->top.ResetIfWin(this);
1434 constr->right.ResetIfWin(this);
1435 constr->bottom.ResetIfWin(this);
1436 constr->width.ResetIfWin(this);
1437 constr->height.ResetIfWin(this);
1438 constr->centreX.ResetIfWin(this);
1439 constr->centreY.ResetIfWin(this);
1440 }
1441
1442 wxWindowList::Node *next = node->GetNext();
1443 delete node;
1444 node = next;
1445 }
1446
1447 delete m_constraintsInvolvedIn;
1448 m_constraintsInvolvedIn = (wxWindowList *) NULL;
1449 }
1450 }
1451
1452 #endif // wxUSE_CONSTRAINTS
1453
1454 void wxWindowBase::SetSizer(wxSizer *sizer, bool deleteOld)
1455 {
1456 if ( deleteOld )
1457 delete m_windowSizer;
1458
1459 m_windowSizer = sizer;
1460
1461 SetAutoLayout( sizer != NULL );
1462 }
1463
1464 void wxWindowBase::SetSizerAndFit(wxSizer *sizer, bool deleteOld)
1465 {
1466 SetSizer( sizer, deleteOld );
1467 sizer->SetSizeHints( (wxWindow*) this );
1468 }
1469
1470 #if wxUSE_CONSTRAINTS
1471
1472 void wxWindowBase::SatisfyConstraints()
1473 {
1474 wxLayoutConstraints *constr = GetConstraints();
1475 bool wasOk = constr && constr->AreSatisfied();
1476
1477 ResetConstraints(); // Mark all constraints as unevaluated
1478
1479 int noChanges = 1;
1480
1481 // if we're a top level panel (i.e. our parent is frame/dialog), our
1482 // own constraints will never be satisfied any more unless we do it
1483 // here
1484 if ( wasOk )
1485 {
1486 while ( noChanges > 0 )
1487 {
1488 LayoutPhase1(&noChanges);
1489 }
1490 }
1491
1492 LayoutPhase2(&noChanges);
1493 }
1494
1495 #endif // wxUSE_CONSTRAINTS
1496
1497 bool wxWindowBase::Layout()
1498 {
1499 // If there is a sizer, use it instead of the constraints
1500 if ( GetSizer() )
1501 {
1502 int w, h;
1503 GetVirtualSize(&w, &h);
1504 GetSizer()->SetDimension( 0, 0, w, h );
1505 }
1506 #if wxUSE_CONSTRAINTS
1507 else
1508 {
1509 SatisfyConstraints(); // Find the right constraints values
1510 SetConstraintSizes(); // Recursively set the real window sizes
1511 }
1512 #endif
1513
1514 return TRUE;
1515 }
1516
1517 #if wxUSE_CONSTRAINTS
1518
1519 // first phase of the constraints evaluation: set our own constraints
1520 bool wxWindowBase::LayoutPhase1(int *noChanges)
1521 {
1522 wxLayoutConstraints *constr = GetConstraints();
1523
1524 return !constr || constr->SatisfyConstraints(this, noChanges);
1525 }
1526
1527 // second phase: set the constraints for our children
1528 bool wxWindowBase::LayoutPhase2(int *noChanges)
1529 {
1530 *noChanges = 0;
1531
1532 // Layout children
1533 DoPhase(1);
1534
1535 // Layout grand children
1536 DoPhase(2);
1537
1538 return TRUE;
1539 }
1540
1541 // Do a phase of evaluating child constraints
1542 bool wxWindowBase::DoPhase(int phase)
1543 {
1544 // the list containing the children for which the constraints are already
1545 // set correctly
1546 wxWindowList succeeded;
1547
1548 // the max number of iterations we loop before concluding that we can't set
1549 // the constraints
1550 static const int maxIterations = 500;
1551
1552 for ( int noIterations = 0; noIterations < maxIterations; noIterations++ )
1553 {
1554 int noChanges = 0;
1555
1556 // loop over all children setting their constraints
1557 for ( wxWindowList::Node *node = GetChildren().GetFirst();
1558 node;
1559 node = node->GetNext() )
1560 {
1561 wxWindow *child = node->GetData();
1562 if ( child->IsTopLevel() )
1563 {
1564 // top level children are not inside our client area
1565 continue;
1566 }
1567
1568 if ( !child->GetConstraints() || succeeded.Find(child) )
1569 {
1570 // this one is either already ok or nothing we can do about it
1571 continue;
1572 }
1573
1574 int tempNoChanges = 0;
1575 bool success = phase == 1 ? child->LayoutPhase1(&tempNoChanges)
1576 : child->LayoutPhase2(&tempNoChanges);
1577 noChanges += tempNoChanges;
1578
1579 if ( success )
1580 {
1581 succeeded.Append(child);
1582 }
1583 }
1584
1585 if ( !noChanges )
1586 {
1587 // constraints are set
1588 break;
1589 }
1590 }
1591
1592 return TRUE;
1593 }
1594
1595 void wxWindowBase::ResetConstraints()
1596 {
1597 wxLayoutConstraints *constr = GetConstraints();
1598 if ( constr )
1599 {
1600 constr->left.SetDone(FALSE);
1601 constr->top.SetDone(FALSE);
1602 constr->right.SetDone(FALSE);
1603 constr->bottom.SetDone(FALSE);
1604 constr->width.SetDone(FALSE);
1605 constr->height.SetDone(FALSE);
1606 constr->centreX.SetDone(FALSE);
1607 constr->centreY.SetDone(FALSE);
1608 }
1609
1610 wxWindowList::Node *node = GetChildren().GetFirst();
1611 while (node)
1612 {
1613 wxWindow *win = node->GetData();
1614 if ( !win->IsTopLevel() )
1615 win->ResetConstraints();
1616 node = node->GetNext();
1617 }
1618 }
1619
1620 // Need to distinguish between setting the 'fake' size for windows and sizers,
1621 // and setting the real values.
1622 void wxWindowBase::SetConstraintSizes(bool recurse)
1623 {
1624 wxLayoutConstraints *constr = GetConstraints();
1625 if ( constr && constr->AreSatisfied() )
1626 {
1627 int x = constr->left.GetValue();
1628 int y = constr->top.GetValue();
1629 int w = constr->width.GetValue();
1630 int h = constr->height.GetValue();
1631
1632 if ( (constr->width.GetRelationship() != wxAsIs ) ||
1633 (constr->height.GetRelationship() != wxAsIs) )
1634 {
1635 SetSize(x, y, w, h);
1636 }
1637 else
1638 {
1639 // If we don't want to resize this window, just move it...
1640 Move(x, y);
1641 }
1642 }
1643 else if ( constr )
1644 {
1645 wxLogDebug(wxT("Constraints not satisfied for %s named '%s'."),
1646 GetClassInfo()->GetClassName(),
1647 GetName().c_str());
1648 }
1649
1650 if ( recurse )
1651 {
1652 wxWindowList::Node *node = GetChildren().GetFirst();
1653 while (node)
1654 {
1655 wxWindow *win = node->GetData();
1656 if ( !win->IsTopLevel() && win->GetConstraints() )
1657 win->SetConstraintSizes();
1658 node = node->GetNext();
1659 }
1660 }
1661 }
1662
1663 // Only set the size/position of the constraint (if any)
1664 void wxWindowBase::SetSizeConstraint(int x, int y, int w, int h)
1665 {
1666 wxLayoutConstraints *constr = GetConstraints();
1667 if ( constr )
1668 {
1669 if ( x != -1 )
1670 {
1671 constr->left.SetValue(x);
1672 constr->left.SetDone(TRUE);
1673 }
1674 if ( y != -1 )
1675 {
1676 constr->top.SetValue(y);
1677 constr->top.SetDone(TRUE);
1678 }
1679 if ( w != -1 )
1680 {
1681 constr->width.SetValue(w);
1682 constr->width.SetDone(TRUE);
1683 }
1684 if ( h != -1 )
1685 {
1686 constr->height.SetValue(h);
1687 constr->height.SetDone(TRUE);
1688 }
1689 }
1690 }
1691
1692 void wxWindowBase::MoveConstraint(int x, int y)
1693 {
1694 wxLayoutConstraints *constr = GetConstraints();
1695 if ( constr )
1696 {
1697 if ( x != -1 )
1698 {
1699 constr->left.SetValue(x);
1700 constr->left.SetDone(TRUE);
1701 }
1702 if ( y != -1 )
1703 {
1704 constr->top.SetValue(y);
1705 constr->top.SetDone(TRUE);
1706 }
1707 }
1708 }
1709
1710 void wxWindowBase::GetSizeConstraint(int *w, int *h) const
1711 {
1712 wxLayoutConstraints *constr = GetConstraints();
1713 if ( constr )
1714 {
1715 *w = constr->width.GetValue();
1716 *h = constr->height.GetValue();
1717 }
1718 else
1719 GetSize(w, h);
1720 }
1721
1722 void wxWindowBase::GetClientSizeConstraint(int *w, int *h) const
1723 {
1724 wxLayoutConstraints *constr = GetConstraints();
1725 if ( constr )
1726 {
1727 *w = constr->width.GetValue();
1728 *h = constr->height.GetValue();
1729 }
1730 else
1731 GetClientSize(w, h);
1732 }
1733
1734 void wxWindowBase::GetPositionConstraint(int *x, int *y) const
1735 {
1736 wxLayoutConstraints *constr = GetConstraints();
1737 if ( constr )
1738 {
1739 *x = constr->left.GetValue();
1740 *y = constr->top.GetValue();
1741 }
1742 else
1743 GetPosition(x, y);
1744 }
1745
1746 #endif // wxUSE_CONSTRAINTS
1747
1748 void wxWindowBase::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) const
1749 {
1750 // don't do it for the dialogs/frames - they float independently of their
1751 // parent
1752 if ( !IsTopLevel() )
1753 {
1754 wxWindow *parent = GetParent();
1755 if ( !(sizeFlags & wxSIZE_NO_ADJUSTMENTS) && parent )
1756 {
1757 wxPoint pt(parent->GetClientAreaOrigin());
1758 x += pt.x;
1759 y += pt.y;
1760 }
1761 }
1762 }
1763
1764 // ----------------------------------------------------------------------------
1765 // do Update UI processing for child controls
1766 // ----------------------------------------------------------------------------
1767
1768 // TODO: should this be implemented for the child window rather
1769 // than the parent? Then you can override it e.g. for wxCheckBox
1770 // to do the Right Thing rather than having to assume a fixed number
1771 // of control classes.
1772 void wxWindowBase::UpdateWindowUI()
1773 {
1774 #if wxUSE_CONTROLS
1775 wxUpdateUIEvent event(GetId());
1776 event.m_eventObject = this;
1777
1778 if ( GetEventHandler()->ProcessEvent(event) )
1779 {
1780 if ( event.GetSetEnabled() )
1781 Enable(event.GetEnabled());
1782
1783 if ( event.GetSetText() )
1784 {
1785 wxControl *control = wxDynamicCastThis(wxControl);
1786 if ( control )
1787 {
1788 #if wxUSE_TEXTCTRL
1789 wxTextCtrl *text = wxDynamicCast(control, wxTextCtrl);
1790 if ( text )
1791 {
1792 if ( event.GetText() != text->GetValue() )
1793 text->SetValue(event.GetText());
1794 }
1795 else
1796 #endif // wxUSE_TEXTCTRL
1797 {
1798 if ( event.GetText() != control->GetLabel() )
1799 control->SetLabel(event.GetText());
1800 }
1801 }
1802 }
1803
1804 #if wxUSE_CHECKBOX
1805 wxCheckBox *checkbox = wxDynamicCastThis(wxCheckBox);
1806 if ( checkbox )
1807 {
1808 if ( event.GetSetChecked() )
1809 checkbox->SetValue(event.GetChecked());
1810 }
1811 #endif // wxUSE_CHECKBOX
1812
1813 #if wxUSE_RADIOBTN
1814 wxRadioButton *radiobtn = wxDynamicCastThis(wxRadioButton);
1815 if ( radiobtn )
1816 {
1817 if ( event.GetSetChecked() )
1818 radiobtn->SetValue(event.GetChecked());
1819 }
1820 #endif // wxUSE_RADIOBTN
1821 }
1822 #endif // wxUSE_CONTROLS
1823 }
1824
1825 // ----------------------------------------------------------------------------
1826 // dialog units translations
1827 // ----------------------------------------------------------------------------
1828
1829 wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt)
1830 {
1831 int charWidth = GetCharWidth();
1832 int charHeight = GetCharHeight();
1833 wxPoint pt2(-1, -1);
1834 if (pt.x != -1)
1835 pt2.x = (int) ((pt.x * 4) / charWidth) ;
1836 if (pt.y != -1)
1837 pt2.y = (int) ((pt.y * 8) / charHeight) ;
1838
1839 return pt2;
1840 }
1841
1842 wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt)
1843 {
1844 int charWidth = GetCharWidth();
1845 int charHeight = GetCharHeight();
1846 wxPoint pt2(-1, -1);
1847 if (pt.x != -1)
1848 pt2.x = (int) ((pt.x * charWidth) / 4) ;
1849 if (pt.y != -1)
1850 pt2.y = (int) ((pt.y * charHeight) / 8) ;
1851
1852 return pt2;
1853 }
1854
1855 // ----------------------------------------------------------------------------
1856 // event handlers
1857 // ----------------------------------------------------------------------------
1858
1859 // propagate the colour change event to the subwindows
1860 void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
1861 {
1862 wxWindowList::Node *node = GetChildren().GetFirst();
1863 while ( node )
1864 {
1865 // Only propagate to non-top-level windows
1866 wxWindow *win = node->GetData();
1867 if ( !win->IsTopLevel() )
1868 {
1869 wxSysColourChangedEvent event2;
1870 event.m_eventObject = win;
1871 win->GetEventHandler()->ProcessEvent(event2);
1872 }
1873
1874 node = node->GetNext();
1875 }
1876 }
1877
1878 // the default action is to populate dialog with data when it's created
1879 void wxWindowBase::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
1880 {
1881 TransferDataToWindow();
1882 }
1883
1884 // process Ctrl-Alt-mclick
1885 void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
1886 {
1887 #if wxUSE_MSGDLG
1888 if ( event.ControlDown() && event.AltDown() )
1889 {
1890 // don't translate these strings
1891 wxString port;
1892
1893 #ifdef __WXUNIVERSAL__
1894 port = _T("Univ/");
1895 #endif // __WXUNIVERSAL__
1896
1897 switch ( wxGetOsVersion() )
1898 {
1899 case wxMOTIF_X: port += _T("Motif"); break;
1900 case wxMAC:
1901 case wxMAC_DARWIN: port += _T("Mac"); break;
1902 case wxBEOS: port += _T("BeOS"); break;
1903 case wxGTK:
1904 case wxGTK_WIN32:
1905 case wxGTK_OS2:
1906 case wxGTK_BEOS: port += _T("GTK"); break;
1907 case wxWINDOWS:
1908 case wxPENWINDOWS:
1909 case wxWINDOWS_NT:
1910 case wxWIN32S:
1911 case wxWIN95:
1912 case wxWIN386: port += _T("MS Windows"); break;
1913 case wxMGL_UNIX:
1914 case wxMGL_X:
1915 case wxMGL_WIN32:
1916 case wxMGL_OS2: port += _T("MGL"); break;
1917 case wxWINDOWS_OS2:
1918 case wxOS2_PM: port += _T("OS/2"); break;
1919 default: port += _T("unknown"); break;
1920 }
1921
1922 wxMessageBox(wxString::Format(
1923 _T(
1924 " wxWindows Library (%s port)\nVersion %u.%u.%u%s, compiled at %s %s\n Copyright (c) 1995-2002 wxWindows team"
1925 ),
1926 port.c_str(),
1927 wxMAJOR_VERSION,
1928 wxMINOR_VERSION,
1929 wxRELEASE_NUMBER,
1930 #if wxUSE_UNICODE
1931 L" (Unicode)",
1932 #else
1933 "",
1934 #endif
1935 __TDATE__,
1936 __TTIME__
1937 ),
1938 _T("wxWindows information"),
1939 wxICON_INFORMATION | wxOK,
1940 (wxWindow *)this);
1941 }
1942 else
1943 #endif // wxUSE_MSGDLG
1944 {
1945 event.Skip();
1946 }
1947 }
1948
1949 // ----------------------------------------------------------------------------
1950 // accessibility
1951 // ----------------------------------------------------------------------------
1952
1953 #if wxUSE_ACCESSIBILITY
1954 void wxWindowBase::SetAccessible(wxAccessible* accessible)
1955 {
1956 if (m_accessible)
1957 delete m_accessible;
1958 m_accessible = accessible;
1959 if (m_accessible)
1960 m_accessible->SetWindow((wxWindow*) this);
1961 }
1962
1963 // Returns the accessible object, creating if necessary.
1964 wxAccessible* wxWindowBase::GetOrCreateAccessible()
1965 {
1966 if (!m_accessible)
1967 m_accessible = CreateAccessible();
1968 return m_accessible;
1969 }
1970
1971 // Override to create a specific accessible object.
1972 wxAccessible* wxWindowBase::CreateAccessible()
1973 {
1974 return new wxWindowAccessible((wxWindow*) this);
1975 }
1976
1977 #endif
1978
1979 // ----------------------------------------------------------------------------
1980 // list classes implementation
1981 // ----------------------------------------------------------------------------
1982
1983 void wxWindowListNode::DeleteData()
1984 {
1985 delete (wxWindow *)GetData();
1986 }
1987
1988 // ----------------------------------------------------------------------------
1989 // borders
1990 // ----------------------------------------------------------------------------
1991
1992 wxBorder wxWindowBase::GetBorder() const
1993 {
1994 wxBorder border = (wxBorder)(m_windowStyle & wxBORDER_MASK);
1995 if ( border == wxBORDER_DEFAULT )
1996 {
1997 border = GetDefaultBorder();
1998 }
1999
2000 return border;
2001 }
2002
2003 wxBorder wxWindowBase::GetDefaultBorder() const
2004 {
2005 return wxBORDER_NONE;
2006 }
2007
2008 // ----------------------------------------------------------------------------
2009 // hit testing
2010 // ----------------------------------------------------------------------------
2011
2012 wxHitTest wxWindowBase::DoHitTest(wxCoord x, wxCoord y) const
2013 {
2014 // here we just check if the point is inside the window or not
2015
2016 // check the top and left border first
2017 bool outside = x < 0 || y < 0;
2018 if ( !outside )
2019 {
2020 // check the right and bottom borders too
2021 wxSize size = GetSize();
2022 outside = x >= size.x || y >= size.y;
2023 }
2024
2025 return outside ? wxHT_WINDOW_OUTSIDE : wxHT_WINDOW_INSIDE;
2026 }
2027
2028 // ----------------------------------------------------------------------------
2029 // mouse capture
2030 // ----------------------------------------------------------------------------
2031
2032 struct WXDLLEXPORT wxWindowNext
2033 {
2034 wxWindow *win;
2035 wxWindowNext *next;
2036 } *wxWindowBase::ms_winCaptureNext = NULL;
2037
2038 void wxWindowBase::CaptureMouse()
2039 {
2040 wxLogTrace(_T("mousecapture"), _T("CaptureMouse(%p)"), this);
2041
2042 wxWindow *winOld = GetCapture();
2043 if ( winOld )
2044 {
2045 ((wxWindowBase*) winOld)->DoReleaseMouse();
2046
2047 // save it on stack
2048 wxWindowNext *item = new wxWindowNext;
2049 item->win = winOld;
2050 item->next = ms_winCaptureNext;
2051 ms_winCaptureNext = item;
2052 }
2053 //else: no mouse capture to save
2054
2055 DoCaptureMouse();
2056 }
2057
2058 void wxWindowBase::ReleaseMouse()
2059 {
2060 wxLogTrace(_T("mousecapture"), _T("ReleaseMouse(%p)"), this);
2061
2062 wxASSERT_MSG( GetCapture() == this, wxT("attempt to release mouse, but this window hasn't captured it") );
2063
2064 DoReleaseMouse();
2065
2066 if ( ms_winCaptureNext )
2067 {
2068 ((wxWindowBase*)ms_winCaptureNext->win)->DoCaptureMouse();
2069
2070 wxWindowNext *item = ms_winCaptureNext;
2071 ms_winCaptureNext = item->next;
2072 delete item;
2073 }
2074 //else: stack is empty, no previous capture
2075
2076 wxLogTrace(_T("mousecapture"),
2077 _T("After ReleaseMouse() mouse is captured by %p"),
2078 GetCapture());
2079 }
2080
2081 // ----------------------------------------------------------------------------
2082 // global functions
2083 // ----------------------------------------------------------------------------
2084
2085 wxWindow* wxGetTopLevelParent(wxWindow *win)
2086 {
2087 while ( win && !win->IsTopLevel() )
2088 win = win->GetParent();
2089
2090 return win;
2091 }
2092
2093 #if wxUSE_ACCESSIBILITY
2094 // ----------------------------------------------------------------------------
2095 // accessible object for windows
2096 // ----------------------------------------------------------------------------
2097
2098 // Can return either a child object, or an integer
2099 // representing the child element, starting from 1.
2100 wxAccStatus wxWindowAccessible::HitTest(const wxPoint& pt, int* childId, wxAccessible** childObject)
2101 {
2102 wxASSERT( GetWindow() != NULL );
2103 if (!GetWindow())
2104 return wxACC_FAIL;
2105
2106 return wxACC_NOT_IMPLEMENTED;
2107 }
2108
2109 // Returns the rectangle for this object (id = 0) or a child element (id > 0).
2110 wxAccStatus wxWindowAccessible::GetLocation(wxRect& rect, int elementId)
2111 {
2112 wxASSERT( GetWindow() != NULL );
2113 if (!GetWindow())
2114 return wxACC_FAIL;
2115
2116 wxWindow* win = NULL;
2117 if (elementId == 0)
2118 {
2119 win = GetWindow();
2120 }
2121 else
2122 {
2123 if (elementId <= (int) GetWindow()->GetChildren().GetCount())
2124 {
2125 win = (wxWindow*) GetWindow()->GetChildren().Nth(elementId-1)->GetData();
2126 }
2127 else
2128 return wxACC_FAIL;
2129 }
2130 if (win)
2131 {
2132 rect = win->GetRect();
2133 if (win->GetParent() && !win->IsKindOf(CLASSINFO(wxTopLevelWindow)))
2134 rect.SetPosition(win->GetParent()->ClientToScreen(rect.GetPosition()));
2135 return wxACC_OK;
2136 }
2137
2138 return wxACC_NOT_IMPLEMENTED;
2139 }
2140
2141 // Navigates from fromId to toId/toObject.
2142 wxAccStatus wxWindowAccessible::Navigate(wxNavDir navDir, int fromId,
2143 int* toId, wxAccessible** toObject)
2144 {
2145 wxASSERT( GetWindow() != NULL );
2146 if (!GetWindow())
2147 return wxACC_FAIL;
2148
2149 switch (navDir)
2150 {
2151 case wxNAVDIR_FIRSTCHILD:
2152 {
2153 if (GetWindow()->GetChildren().GetCount() == 0)
2154 return wxACC_FALSE;
2155 wxWindow* childWindow = (wxWindow*) GetWindow()->GetChildren().GetFirst()->GetData();
2156 *toObject = childWindow->GetOrCreateAccessible();
2157
2158 return wxACC_OK;
2159 }
2160 case wxNAVDIR_LASTCHILD:
2161 {
2162 if (GetWindow()->GetChildren().GetCount() == 0)
2163 return wxACC_FALSE;
2164 wxWindow* childWindow = (wxWindow*) GetWindow()->GetChildren().GetLast()->GetData();
2165 *toObject = childWindow->GetOrCreateAccessible();
2166
2167 return wxACC_OK;
2168 }
2169 case wxNAVDIR_RIGHT:
2170 case wxNAVDIR_DOWN:
2171 case wxNAVDIR_NEXT:
2172 {
2173 wxWindowList::Node *node = NULL;
2174 if (fromId == 0)
2175 {
2176 // Can't navigate to sibling of this window
2177 // if we're a top-level window.
2178 if (!GetWindow()->GetParent())
2179 return wxACC_NOT_IMPLEMENTED;
2180
2181 node = GetWindow()->GetParent()->GetChildren().Find(GetWindow());
2182 }
2183 else
2184 {
2185 if (fromId <= (int) GetWindow()->GetChildren().GetCount())
2186 node = (wxWindowList::Node*) GetWindow()->GetChildren().Nth(fromId-1);
2187 }
2188
2189 if (node && node->GetNext())
2190 {
2191 wxWindow* nextWindow = (wxWindow*) node->GetNext()->Data();
2192 *toObject = nextWindow->GetOrCreateAccessible();
2193 return wxACC_OK;
2194 }
2195 else
2196 return wxACC_FALSE;
2197 }
2198 case wxNAVDIR_LEFT:
2199 case wxNAVDIR_UP:
2200 case wxNAVDIR_PREVIOUS:
2201 {
2202 wxWindowList::Node *node = NULL;
2203 if (fromId == 0)
2204 {
2205 // Can't navigate to sibling of this window
2206 // if we're a top-level window.
2207 if (!GetWindow()->GetParent())
2208 return wxACC_NOT_IMPLEMENTED;
2209
2210 node = GetWindow()->GetParent()->GetChildren().Find(GetWindow());
2211 }
2212 else
2213 {
2214 if (fromId <= (int) GetWindow()->GetChildren().GetCount())
2215 node = (wxWindowList::Node*) GetWindow()->GetChildren().Nth(fromId-1);
2216 }
2217
2218 if (node && node->GetPrevious())
2219 {
2220 wxWindow* previousWindow = (wxWindow*) node->GetPrevious()->Data();
2221 *toObject = previousWindow->GetOrCreateAccessible();
2222 return wxACC_OK;
2223 }
2224 else
2225 return wxACC_FALSE;
2226 }
2227 }
2228
2229 return wxACC_NOT_IMPLEMENTED;
2230 }
2231
2232 // Gets the name of the specified object.
2233 wxAccStatus wxWindowAccessible::GetName(int childId, wxString* name)
2234 {
2235 wxASSERT( GetWindow() != NULL );
2236 if (!GetWindow())
2237 return wxACC_FAIL;
2238
2239 wxString title(GetWindow()->GetTitle());
2240 if (!title.IsEmpty())
2241 {
2242 *name = title;
2243 return wxACC_OK;
2244 }
2245 else
2246 return wxACC_NOT_IMPLEMENTED;
2247 }
2248
2249 // Gets the number of children.
2250 wxAccStatus wxWindowAccessible::GetChildCount(int* childId)
2251 {
2252 wxASSERT( GetWindow() != NULL );
2253 if (!GetWindow())
2254 return wxACC_FAIL;
2255
2256 *childId = (int) GetWindow()->GetChildren().GetCount();
2257 return wxACC_OK;
2258 }
2259
2260 // Gets the specified child (starting from 1).
2261 // If *child is NULL and return value is wxACC_OK,
2262 // this means that the child is a simple element and
2263 // not an accessible object.
2264 wxAccStatus wxWindowAccessible::GetChild(int childId, wxAccessible** child)
2265 {
2266 wxASSERT( GetWindow() != NULL );
2267 if (!GetWindow())
2268 return wxACC_FAIL;
2269
2270 if (childId == 0)
2271 {
2272 *child = this;
2273 return wxACC_OK;
2274 }
2275
2276 if (childId > (int) GetWindow()->GetChildren().GetCount())
2277 return wxACC_FAIL;
2278
2279 wxWindow* childWindow = (wxWindow*) GetWindow()->GetChildren().Nth(childId-1)->GetData();
2280 *child = childWindow->GetOrCreateAccessible();
2281 if (*child)
2282 return wxACC_OK;
2283 else
2284 return wxACC_FAIL;
2285 }
2286
2287 // Gets the parent, or NULL.
2288 wxAccStatus wxWindowAccessible::GetParent(wxAccessible** parent)
2289 {
2290 wxASSERT( GetWindow() != NULL );
2291 if (!GetWindow())
2292 return wxACC_FAIL;
2293
2294 wxWindow* parentWindow = GetWindow()->GetParent();
2295 if (!parentWindow)
2296 {
2297 *parent = NULL;
2298 return wxACC_OK;
2299 }
2300 else
2301 {
2302 *parent = parentWindow->GetOrCreateAccessible();
2303 if (*parent)
2304 return wxACC_OK;
2305 else
2306 return wxACC_FAIL;
2307 }
2308 }
2309
2310 // Performs the default action. childId is 0 (the action for this object)
2311 // or > 0 (the action for a child).
2312 // Return wxACC_NOT_SUPPORTED if there is no default action for this
2313 // window (e.g. an edit control).
2314 wxAccStatus wxWindowAccessible::DoDefaultAction(int childId)
2315 {
2316 wxASSERT( GetWindow() != NULL );
2317 if (!GetWindow())
2318 return wxACC_FAIL;
2319
2320 return wxACC_NOT_IMPLEMENTED;
2321 }
2322
2323 // Gets the default action for this object (0) or > 0 (the action for a child).
2324 // Return wxACC_OK even if there is no action. actionName is the action, or the empty
2325 // string if there is no action.
2326 // The retrieved string describes the action that is performed on an object,
2327 // not what the object does as a result. For example, a toolbar button that prints
2328 // a document has a default action of "Press" rather than "Prints the current document."
2329 wxAccStatus wxWindowAccessible::GetDefaultAction(int childId, wxString* actionName)
2330 {
2331 wxASSERT( GetWindow() != NULL );
2332 if (!GetWindow())
2333 return wxACC_FAIL;
2334
2335 return wxACC_NOT_IMPLEMENTED;
2336 }
2337
2338 // Returns the description for this object or a child.
2339 wxAccStatus wxWindowAccessible::GetDescription(int childId, wxString* description)
2340 {
2341 wxASSERT( GetWindow() != NULL );
2342 if (!GetWindow())
2343 return wxACC_FAIL;
2344
2345 return wxACC_NOT_IMPLEMENTED;
2346 }
2347
2348 // Returns help text for this object or a child, similar to tooltip text.
2349 wxAccStatus wxWindowAccessible::GetHelpText(int childId, wxString* helpText)
2350 {
2351 wxASSERT( GetWindow() != NULL );
2352 if (!GetWindow())
2353 return wxACC_FAIL;
2354
2355 wxString ht(GetWindow()->GetHelpText());
2356 if (!ht.IsEmpty())
2357 {
2358 *helpText = ht;
2359 return wxACC_OK;
2360 }
2361 return wxACC_NOT_IMPLEMENTED;
2362 }
2363
2364 // Returns the keyboard shortcut for this object or child.
2365 // Return e.g. ALT+K
2366 wxAccStatus wxWindowAccessible::GetKeyboardShortcut(int childId, wxString* shortcut)
2367 {
2368 wxASSERT( GetWindow() != NULL );
2369 if (!GetWindow())
2370 return wxACC_FAIL;
2371
2372 return wxACC_NOT_IMPLEMENTED;
2373 }
2374
2375 // Returns a role constant.
2376 wxAccStatus wxWindowAccessible::GetRole(int childId, wxAccRole* role)
2377 {
2378 wxASSERT( GetWindow() != NULL );
2379 if (!GetWindow())
2380 return wxACC_FAIL;
2381
2382 return wxACC_NOT_IMPLEMENTED;
2383 }
2384
2385 // Returns a state constant.
2386 wxAccStatus wxWindowAccessible::GetState(int childId, long* state)
2387 {
2388 wxASSERT( GetWindow() != NULL );
2389 if (!GetWindow())
2390 return wxACC_FAIL;
2391
2392 return wxACC_NOT_IMPLEMENTED;
2393 }
2394
2395 // Returns a localized string representing the value for the object
2396 // or child.
2397 wxAccStatus wxWindowAccessible::GetValue(int childId, wxString* strValue)
2398 {
2399 wxASSERT( GetWindow() != NULL );
2400 if (!GetWindow())
2401 return wxACC_FAIL;
2402
2403 return wxACC_NOT_IMPLEMENTED;
2404 }
2405
2406 // Selects the object or child.
2407 wxAccStatus wxWindowAccessible::Select(int childId, wxAccSelectionFlags selectFlags)
2408 {
2409 wxASSERT( GetWindow() != NULL );
2410 if (!GetWindow())
2411 return wxACC_FAIL;
2412
2413 return wxACC_NOT_IMPLEMENTED;
2414 }
2415
2416 // Gets the window with the keyboard focus.
2417 // If childId is 0 and child is NULL, no object in
2418 // this subhierarchy has the focus.
2419 // If this object has the focus, child should be 'this'.
2420 wxAccStatus wxWindowAccessible::GetFocus(int* childId, wxAccessible** child)
2421 {
2422 wxASSERT( GetWindow() != NULL );
2423 if (!GetWindow())
2424 return wxACC_FAIL;
2425
2426 return wxACC_NOT_IMPLEMENTED;
2427 }
2428
2429 // Gets a variant representing the selected children
2430 // of this object.
2431 // Acceptable values:
2432 // - a null variant (IsNull() returns TRUE)
2433 // - a list variant (GetType() == wxT("list")
2434 // - an integer representing the selected child element,
2435 // or 0 if this object is selected (GetType() == wxT("long")
2436 // - a "void*" pointer to a wxAccessible child object
2437 wxAccStatus wxWindowAccessible::GetSelections(wxVariant* selections)
2438 {
2439 wxASSERT( GetWindow() != NULL );
2440 if (!GetWindow())
2441 return wxACC_FAIL;
2442
2443 return wxACC_NOT_IMPLEMENTED;
2444 }
2445
2446 #endif // wxUSE_ACCESSIBILITY