]> git.saurik.com Git - wxWidgets.git/blob - src/common/wincmn.cpp
corrected constness
[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/textctrl.h"
42 #include "wx/settings.h"
43 #include "wx/dialog.h"
44 #include "wx/msgdlg.h"
45 #include "wx/statusbr.h"
46 #endif //WX_PRECOMP
47
48 #if wxUSE_CONSTRAINTS
49 #include "wx/layout.h"
50 #include "wx/sizer.h"
51 #endif // wxUSE_CONSTRAINTS
52
53 #if wxUSE_DRAG_AND_DROP
54 #include "wx/dnd.h"
55 #endif // wxUSE_DRAG_AND_DROP
56
57 #if wxUSE_HELP
58 #include "wx/cshelp.h"
59 #endif // wxUSE_HELP
60
61 #if wxUSE_TOOLTIPS
62 #include "wx/tooltip.h"
63 #endif // wxUSE_TOOLTIPS
64
65 #if wxUSE_CARET
66 #include "wx/caret.h"
67 #endif // wxUSE_CARET
68
69 // ----------------------------------------------------------------------------
70 // static data
71 // ----------------------------------------------------------------------------
72
73 int wxWindowBase::ms_lastControlId = -200;
74
75 IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
76
77 // ----------------------------------------------------------------------------
78 // event table
79 // ----------------------------------------------------------------------------
80
81 BEGIN_EVENT_TABLE(wxWindowBase, wxEvtHandler)
82 EVT_SYS_COLOUR_CHANGED(wxWindowBase::OnSysColourChanged)
83 EVT_INIT_DIALOG(wxWindowBase::OnInitDialog)
84 EVT_MIDDLE_DOWN(wxWindowBase::OnMiddleClick)
85
86 #if wxUSE_HELP
87 EVT_HELP(-1, wxWindowBase::OnHelp)
88 #endif // wxUSE_HELP
89
90 END_EVENT_TABLE()
91
92 // ============================================================================
93 // implementation of the common functionality of the wxWindow class
94 // ============================================================================
95
96 // ----------------------------------------------------------------------------
97 // initialization
98 // ----------------------------------------------------------------------------
99
100 // the default initialization
101 void wxWindowBase::InitBase()
102 {
103 // no window yet, no parent nor children
104 m_parent = (wxWindow *)NULL;
105 m_windowId = -1;
106 m_children.DeleteContents( FALSE ); // don't auto delete node data
107
108 // no constraints on the minimal window size
109 m_minWidth =
110 m_minHeight =
111 m_maxWidth =
112 m_maxHeight = -1;
113
114 // window is created enabled but it's not visible yet
115 m_isShown = FALSE;
116 m_isEnabled = TRUE;
117
118 // the default event handler is just this window
119 m_eventHandler = this;
120
121 #if wxUSE_VALIDATORS
122 // no validator
123 m_windowValidator = (wxValidator *) NULL;
124 #endif // wxUSE_VALIDATORS
125
126 // use the system default colours
127 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE);
128 m_foregroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT);
129
130 // don't set the font here for wxMSW as we don't call WM_SETFONT here and
131 // so the font is *not* really set - but calls to SetFont() later won't do
132 // anything because m_font appears to be already set!
133 #ifndef __WXMSW__
134 m_font = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
135 #endif // __WXMSW__
136
137 // no style bits
138 m_exStyle =
139 m_windowStyle = 0;
140
141 // an optimization for the event processing: checking this flag is much
142 // faster than using IsKindOf(CLASSINFO(wxWindow))
143 m_isWindow = TRUE;
144
145 #if wxUSE_CONSTRAINTS
146 // no constraints whatsoever
147 m_constraints = (wxLayoutConstraints *) NULL;
148 m_constraintsInvolvedIn = (wxWindowList *) NULL;
149 m_windowSizer = (wxSizer *) NULL;
150 m_autoLayout = FALSE;
151 #endif // wxUSE_CONSTRAINTS
152
153 #if wxUSE_DRAG_AND_DROP
154 m_dropTarget = (wxDropTarget *)NULL;
155 #endif // wxUSE_DRAG_AND_DROP
156
157 #if wxUSE_TOOLTIPS
158 m_tooltip = (wxToolTip *)NULL;
159 #endif // wxUSE_TOOLTIPS
160
161 #if wxUSE_CARET
162 m_caret = (wxCaret *)NULL;
163 #endif // wxUSE_CARET
164
165 // Whether we're using the current theme for this window (wxGTK only for now)
166 m_themeEnabled = FALSE;
167 }
168
169 // common part of window creation process
170 bool wxWindowBase::CreateBase(wxWindowBase *parent,
171 wxWindowID id,
172 const wxPoint& WXUNUSED(pos),
173 const wxSize& WXUNUSED(size),
174 long style,
175 const wxValidator& validator,
176 const wxString& name)
177 {
178 // m_isWindow is set to TRUE in wxWindowBase::Init() as well as many other
179 // member variables - check that it has been called (will catch the case
180 // when a new ctor is added which doesn't call InitWindow)
181 wxASSERT_MSG( m_isWindow, wxT("Init() must have been called before!") );
182
183 // generate a new id if the user doesn't care about it
184 m_windowId = id == -1 ? NewControlId() : id;
185
186 SetName(name);
187 SetWindowStyleFlag(style);
188 SetParent(parent);
189
190 #if wxUSE_VALIDATORS
191 SetValidator(validator);
192 #endif // wxUSE_VALIDATORS
193
194 // if the parent window has wxWS_EX_VALIDATE_RECURSIVELY set, we want to
195 // have it too - like this it's possible to set it only in the top level
196 // dialog/frame and all children will inherit it by defult
197 if ( parent && (parent->GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) )
198 {
199 SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
200 }
201
202 return TRUE;
203 }
204
205 // ----------------------------------------------------------------------------
206 // destruction
207 // ----------------------------------------------------------------------------
208
209 // common clean up
210 wxWindowBase::~wxWindowBase()
211 {
212 // FIXME if these 2 cases result from programming errors in the user code
213 // we should probably assert here instead of silently fixing them
214
215 // Just in case the window has been Closed, but we're then deleting
216 // immediately: don't leave dangling pointers.
217 wxPendingDelete.DeleteObject(this);
218
219 // Just in case we've loaded a top-level window via LoadNativeDialog but
220 // we weren't a dialog class
221 wxTopLevelWindows.DeleteObject(this);
222
223 wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );
224
225 #if wxUSE_CARET
226 if ( m_caret )
227 delete m_caret;
228 #endif // wxUSE_CARET
229
230 #if wxUSE_VALIDATORS
231 if ( m_windowValidator )
232 delete m_windowValidator;
233 #endif // wxUSE_VALIDATORS
234
235 #if wxUSE_CONSTRAINTS
236 // Have to delete constraints/sizer FIRST otherwise sizers may try to look
237 // at deleted windows as they delete themselves.
238 DeleteRelatedConstraints();
239
240 if ( m_constraints )
241 {
242 // This removes any dangling pointers to this window in other windows'
243 // constraintsInvolvedIn lists.
244 UnsetConstraints(m_constraints);
245 delete m_constraints;
246 m_constraints = NULL;
247 }
248
249 if ( m_windowSizer )
250 delete m_windowSizer;
251
252 #endif // wxUSE_CONSTRAINTS
253
254 #if wxUSE_DRAG_AND_DROP
255 if ( m_dropTarget )
256 delete m_dropTarget;
257 #endif // wxUSE_DRAG_AND_DROP
258
259 #if wxUSE_TOOLTIPS
260 if ( m_tooltip )
261 delete m_tooltip;
262 #endif // wxUSE_TOOLTIPS
263
264 // reset the dangling pointer our parent window may keep to us
265 if ( m_parent && m_parent->GetDefaultItem() == this )
266 {
267 m_parent->SetDefaultItem(NULL);
268 }
269 }
270
271 bool wxWindowBase::Destroy()
272 {
273 delete this;
274
275 return TRUE;
276 }
277
278 bool wxWindowBase::Close(bool force)
279 {
280 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
281 event.SetEventObject(this);
282 #if WXWIN_COMPATIBILITY
283 event.SetForce(force);
284 #endif // WXWIN_COMPATIBILITY
285 event.SetCanVeto(!force);
286
287 // return FALSE if window wasn't closed because the application vetoed the
288 // close event
289 return GetEventHandler()->ProcessEvent(event) && !event.GetVeto();
290 }
291
292 bool wxWindowBase::DestroyChildren()
293 {
294 wxWindowList::Node *node;
295 for ( ;; )
296 {
297 // we iterate until the list becomes empty
298 node = GetChildren().GetFirst();
299 if ( !node )
300 break;
301
302 wxWindow *child = node->GetData();
303
304 wxASSERT_MSG( child, wxT("children list contains empty nodes") );
305
306 child->Show(FALSE);
307 delete child;
308
309 wxASSERT_MSG( !GetChildren().Find(child),
310 wxT("child didn't remove itself using RemoveChild()") );
311 }
312
313 return TRUE;
314 }
315
316 // ----------------------------------------------------------------------------
317 // size/position related methods
318 // ----------------------------------------------------------------------------
319
320 // centre the window with respect to its parent in either (or both) directions
321 void wxWindowBase::Centre(int direction)
322 {
323 // the position/size of the parent window or of the entire screen
324 wxPoint posParent;
325 int widthParent, heightParent;
326
327 wxWindow *parent = NULL;
328
329 if ( !(direction & wxCENTRE_ON_SCREEN) )
330 {
331 // find the parent to centre this window on: it should be the
332 // immediate parent for the controls but the top level parent for the
333 // top level windows (like dialogs)
334 parent = GetParent();
335 if ( IsTopLevel() )
336 {
337 while ( parent && !parent->IsTopLevel() )
338 {
339 parent = parent->GetParent();
340 }
341 }
342
343 // did we find the parent?
344 if ( !parent )
345 {
346 // no other choice
347 direction |= wxCENTRE_ON_SCREEN;
348 }
349 }
350
351 if ( direction & wxCENTRE_ON_SCREEN )
352 {
353 // centre with respect to the whole screen
354 wxDisplaySize(&widthParent, &heightParent);
355 }
356 else
357 {
358 if ( IsTopLevel() )
359 {
360 // centre on the parent
361 parent->GetSize(&widthParent, &heightParent);
362
363 // adjust to the parents position
364 posParent = parent->GetPosition();
365 }
366 else
367 {
368 // centre inside the parents client rectangle
369 parent->GetClientSize(&widthParent, &heightParent);
370 }
371 }
372
373 int width, height;
374 GetSize(&width, &height);
375
376 int xNew = -1,
377 yNew = -1;
378
379 if ( direction & wxHORIZONTAL )
380 xNew = (widthParent - width)/2;
381
382 if ( direction & wxVERTICAL )
383 yNew = (heightParent - height)/2;
384
385 xNew += posParent.x;
386 yNew += posParent.y;
387
388 // Base size of the visible dimensions of the display
389 // to take into account the taskbar
390 wxRect rect = wxGetClientDisplayRect();
391 wxSize size (rect.width,rect.height);
392
393 if (posParent.x >= 0) // if parent is on the main display
394 {
395 if (xNew < 0)
396 xNew = 0;
397 else if (xNew+width > size.x)
398 xNew = size.x-width-1;
399 }
400 if (posParent.y >= 0) // if parent is on the main display
401 {
402 if (yNew+height > size.y)
403 yNew = size.y-height-1;
404
405 // Make certain that the title bar is initially visible
406 // always, even if this would push the bottom of the
407 // dialog of the visible area of the display
408 if (yNew < 0)
409 yNew = 0;
410 }
411
412 // move the window to this position (keeping the old size but using
413 // SetSize() and not Move() to allow xNew and/or yNew to be -1)
414 SetSize(xNew, yNew, width, height, wxSIZE_ALLOW_MINUS_ONE);
415 }
416
417 // fits the window around the children
418 void wxWindowBase::Fit()
419 {
420 if ( GetChildren().GetCount() > 0 )
421 {
422 wxSize size = DoGetBestSize();
423
424 // for compatibility with the old versions and because it really looks
425 // slightly more pretty like this, add a pad
426 size.x += 7;
427 size.y += 14;
428
429 SetClientSize(size);
430 }
431 //else: do nothing if we have no children
432 }
433
434 // return the size best suited for the current window
435 wxSize wxWindowBase::DoGetBestSize() const
436 {
437 if ( GetChildren().GetCount() > 0 )
438 {
439 // our minimal acceptable size is such that all our windows fit inside
440 int maxX = 0,
441 maxY = 0;
442
443 for ( wxWindowList::Node *node = GetChildren().GetFirst();
444 node;
445 node = node->GetNext() )
446 {
447 wxWindow *win = node->GetData();
448 if ( win->IsTopLevel()
449 #if wxUSE_STATUSBAR
450 || wxDynamicCast(win, wxStatusBar)
451 #endif // wxUSE_STATUSBAR
452 )
453 {
454 // dialogs and frames lie in different top level windows -
455 // don't deal with them here; as for the status bars, they
456 // don't lie in the client area at all
457 continue;
458 }
459
460 int wx, wy, ww, wh;
461 win->GetPosition(&wx, &wy);
462
463 // if the window hadn't been positioned yet, assume that it is in
464 // the origin
465 if ( wx == -1 )
466 wx = 0;
467 if ( wy == -1 )
468 wy = 0;
469
470 win->GetSize(&ww, &wh);
471 if ( wx + ww > maxX )
472 maxX = wx + ww;
473 if ( wy + wh > maxY )
474 maxY = wy + wh;
475 }
476
477 return wxSize(maxX, maxY);
478 }
479 else
480 {
481 // for a generic window there is no natural best size - just use the
482 // current one
483 return GetSize();
484 }
485 }
486
487 // by default the origin is not shifted
488 wxPoint wxWindowBase::GetClientAreaOrigin() const
489 {
490 return wxPoint(0, 0);
491 }
492
493 // set the min/max size of the window
494 void wxWindowBase::SetSizeHints(int minW, int minH,
495 int maxW, int maxH,
496 int WXUNUSED(incW), int WXUNUSED(incH))
497 {
498 m_minWidth = minW;
499 m_maxWidth = maxW;
500 m_minHeight = minH;
501 m_maxHeight = maxH;
502 }
503
504 // ----------------------------------------------------------------------------
505 // show/hide/enable/disable the window
506 // ----------------------------------------------------------------------------
507
508 bool wxWindowBase::Show(bool show)
509 {
510 if ( show != m_isShown )
511 {
512 m_isShown = show;
513
514 return TRUE;
515 }
516 else
517 {
518 return FALSE;
519 }
520 }
521
522 bool wxWindowBase::Enable(bool enable)
523 {
524 if ( enable != m_isEnabled )
525 {
526 m_isEnabled = enable;
527
528 return TRUE;
529 }
530 else
531 {
532 return FALSE;
533 }
534 }
535 // ----------------------------------------------------------------------------
536 // RTTI
537 // ----------------------------------------------------------------------------
538
539 bool wxWindowBase::IsTopLevel() const
540 {
541 return FALSE;
542 }
543
544 // ----------------------------------------------------------------------------
545 // reparenting the window
546 // ----------------------------------------------------------------------------
547
548 void wxWindowBase::AddChild(wxWindowBase *child)
549 {
550 wxCHECK_RET( child, wxT("can't add a NULL child") );
551
552 // this should never happen and it will lead to a crash later if it does
553 // because RemoveChild() will remove only one node from the children list
554 // and the other(s) one(s) will be left with dangling pointers in them
555 wxASSERT_MSG( !GetChildren().Find(child), _T("AddChild() called twice") );
556
557 GetChildren().Append(child);
558 child->SetParent(this);
559 }
560
561 void wxWindowBase::RemoveChild(wxWindowBase *child)
562 {
563 wxCHECK_RET( child, wxT("can't remove a NULL child") );
564
565 GetChildren().DeleteObject(child);
566 child->SetParent((wxWindow *)NULL);
567 }
568
569 bool wxWindowBase::Reparent(wxWindowBase *newParent)
570 {
571 wxWindow *oldParent = GetParent();
572 if ( newParent == oldParent )
573 {
574 // nothing done
575 return FALSE;
576 }
577
578 // unlink this window from the existing parent.
579 if ( oldParent )
580 {
581 oldParent->RemoveChild(this);
582 }
583 else
584 {
585 wxTopLevelWindows.DeleteObject(this);
586 }
587
588 // add it to the new one
589 if ( newParent )
590 {
591 newParent->AddChild(this);
592 }
593 else
594 {
595 wxTopLevelWindows.Append(this);
596 }
597
598 return TRUE;
599 }
600
601 // ----------------------------------------------------------------------------
602 // event handler stuff
603 // ----------------------------------------------------------------------------
604
605 void wxWindowBase::PushEventHandler(wxEvtHandler *handler)
606 {
607 handler->SetNextHandler(GetEventHandler());
608 SetEventHandler(handler);
609 }
610
611 wxEvtHandler *wxWindowBase::PopEventHandler(bool deleteHandler)
612 {
613 wxEvtHandler *handlerA = GetEventHandler();
614 if ( handlerA )
615 {
616 wxEvtHandler *handlerB = handlerA->GetNextHandler();
617 handlerA->SetNextHandler((wxEvtHandler *)NULL);
618 SetEventHandler(handlerB);
619 if ( deleteHandler )
620 {
621 delete handlerA;
622 handlerA = (wxEvtHandler *)NULL;
623 }
624 }
625
626 return handlerA;
627 }
628
629 // ----------------------------------------------------------------------------
630 // cursors, fonts &c
631 // ----------------------------------------------------------------------------
632
633 bool wxWindowBase::SetBackgroundColour( const wxColour &colour )
634 {
635 if ( !colour.Ok() || (colour == m_backgroundColour) )
636 return FALSE;
637
638 m_backgroundColour = colour;
639
640 m_hasBgCol = TRUE;
641
642 return TRUE;
643 }
644
645 bool wxWindowBase::SetForegroundColour( const wxColour &colour )
646 {
647 if ( !colour.Ok() || (colour == m_foregroundColour) )
648 return FALSE;
649
650 m_foregroundColour = colour;
651
652 m_hasFgCol = TRUE;
653
654 return TRUE;
655 }
656
657 bool wxWindowBase::SetCursor(const wxCursor& cursor)
658 {
659 // setting an invalid cursor is ok, it means that we don't have any special
660 // cursor
661 if ( m_cursor == cursor )
662 {
663 // no change
664 return FALSE;
665 }
666
667 m_cursor = cursor;
668
669 return TRUE;
670 }
671
672 bool wxWindowBase::SetFont(const wxFont& font)
673 {
674 // don't try to set invalid font, always fall back to the default
675 const wxFont& fontOk = font.Ok() ? font : *wxSWISS_FONT;
676
677 if ( fontOk == m_font )
678 {
679 // no change
680 return FALSE;
681 }
682
683 m_font = fontOk;
684
685 m_hasFont = TRUE;
686
687 return TRUE;
688 }
689
690 #if wxUSE_CARET
691 void wxWindowBase::SetCaret(wxCaret *caret)
692 {
693 if ( m_caret )
694 {
695 delete m_caret;
696 }
697
698 m_caret = caret;
699
700 if ( m_caret )
701 {
702 wxASSERT_MSG( m_caret->GetWindow() == this,
703 wxT("caret should be created associated to this window") );
704 }
705 }
706 #endif // wxUSE_CARET
707
708 #if wxUSE_VALIDATORS
709 // ----------------------------------------------------------------------------
710 // validators
711 // ----------------------------------------------------------------------------
712
713 void wxWindowBase::SetValidator(const wxValidator& validator)
714 {
715 if ( m_windowValidator )
716 delete m_windowValidator;
717
718 m_windowValidator = (wxValidator *)validator.Clone();
719
720 if ( m_windowValidator )
721 m_windowValidator->SetWindow(this) ;
722 }
723 #endif // wxUSE_VALIDATORS
724
725 // ----------------------------------------------------------------------------
726 // update region stuff
727 // ----------------------------------------------------------------------------
728
729 wxRect wxWindowBase::GetUpdateClientRect() const
730 {
731 wxRegion rgnUpdate = GetUpdateRegion();
732 rgnUpdate.Intersect(GetClientRect());
733 wxRect rectUpdate = rgnUpdate.GetBox();
734 wxPoint ptOrigin = GetClientAreaOrigin();
735 rectUpdate.x -= ptOrigin.x;
736 rectUpdate.y -= ptOrigin.y;
737
738 return rectUpdate;
739 }
740
741 bool wxWindowBase::IsExposed(int x, int y) const
742 {
743 return m_updateRegion.Contains(x, y) != wxOutRegion;
744 }
745
746 bool wxWindowBase::IsExposed(int x, int y, int w, int h) const
747 {
748 return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
749 }
750
751 // ----------------------------------------------------------------------------
752 // find window by id or name
753 // ----------------------------------------------------------------------------
754
755 wxWindow *wxWindowBase::FindWindow( long id )
756 {
757 if ( id == m_windowId )
758 return (wxWindow *)this;
759
760 wxWindowBase *res = (wxWindow *)NULL;
761 wxWindowList::Node *node;
762 for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
763 {
764 wxWindowBase *child = node->GetData();
765 res = child->FindWindow( id );
766 }
767
768 return (wxWindow *)res;
769 }
770
771 wxWindow *wxWindowBase::FindWindow( const wxString& name )
772 {
773 if ( name == m_windowName )
774 return (wxWindow *)this;
775
776 wxWindowBase *res = (wxWindow *)NULL;
777 wxWindowList::Node *node;
778 for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
779 {
780 wxWindow *child = node->GetData();
781 res = child->FindWindow(name);
782 }
783
784 return (wxWindow *)res;
785 }
786
787 // ----------------------------------------------------------------------------
788 // dialog oriented functions
789 // ----------------------------------------------------------------------------
790
791 void wxWindowBase::MakeModal(bool modal)
792 {
793 // Disable all other windows
794 if ( IsTopLevel() )
795 {
796 wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
797 while (node)
798 {
799 wxWindow *win = node->GetData();
800 if (win != this)
801 win->Enable(!modal);
802
803 node = node->GetNext();
804 }
805 }
806 }
807
808 bool wxWindowBase::Validate()
809 {
810 #if wxUSE_VALIDATORS
811 bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
812
813 wxWindowList::Node *node;
814 for ( node = m_children.GetFirst(); node; node = node->GetNext() )
815 {
816 wxWindowBase *child = node->GetData();
817 wxValidator *validator = child->GetValidator();
818 if ( validator && !validator->Validate((wxWindow *)this) )
819 {
820 return FALSE;
821 }
822
823 if ( recurse && !child->Validate() )
824 {
825 return FALSE;
826 }
827 }
828 #endif // wxUSE_VALIDATORS
829
830 return TRUE;
831 }
832
833 bool wxWindowBase::TransferDataToWindow()
834 {
835 #if wxUSE_VALIDATORS
836 bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
837
838 wxWindowList::Node *node;
839 for ( node = m_children.GetFirst(); node; node = node->GetNext() )
840 {
841 wxWindowBase *child = node->GetData();
842 wxValidator *validator = child->GetValidator();
843 if ( validator && !validator->TransferToWindow() )
844 {
845 wxLogWarning(_("Could not transfer data to window"));
846 wxLog::FlushActive();
847
848 return FALSE;
849 }
850
851 if ( recurse )
852 {
853 if ( !child->TransferDataToWindow() )
854 {
855 // warning already given
856 return FALSE;
857 }
858 }
859 }
860 #endif // wxUSE_VALIDATORS
861
862 return TRUE;
863 }
864
865 bool wxWindowBase::TransferDataFromWindow()
866 {
867 #if wxUSE_VALIDATORS
868 bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
869
870 wxWindowList::Node *node;
871 for ( node = m_children.GetFirst(); node; node = node->GetNext() )
872 {
873 wxWindow *child = node->GetData();
874 wxValidator *validator = child->GetValidator();
875 if ( validator && !validator->TransferFromWindow() )
876 {
877 // nop warning here because the application is supposed to give
878 // one itself - we don't know here what might have gone wrongly
879
880 return FALSE;
881 }
882
883 if ( recurse )
884 {
885 if ( !child->TransferDataFromWindow() )
886 {
887 // warning already given
888 return FALSE;
889 }
890 }
891 }
892 #endif // wxUSE_VALIDATORS
893
894 return TRUE;
895 }
896
897 void wxWindowBase::InitDialog()
898 {
899 wxInitDialogEvent event(GetId());
900 event.SetEventObject( this );
901 GetEventHandler()->ProcessEvent(event);
902 }
903
904 // ----------------------------------------------------------------------------
905 // context-sensitive help support
906 // ----------------------------------------------------------------------------
907
908 #if wxUSE_HELP
909
910 // associate this help text with this window
911 void wxWindowBase::SetHelpText(const wxString& text)
912 {
913 wxHelpProvider *helpProvider = wxHelpProvider::Get();
914 if ( helpProvider )
915 {
916 helpProvider->AddHelp(this, text);
917 }
918 }
919
920 // associate this help text with all windows with the same id as this
921 // one
922 void wxWindowBase::SetHelpTextForId(const wxString& text)
923 {
924 wxHelpProvider *helpProvider = wxHelpProvider::Get();
925 if ( helpProvider )
926 {
927 helpProvider->AddHelp(GetId(), text);
928 }
929 }
930
931 // get the help string associated with this window (may be empty)
932 wxString wxWindowBase::GetHelpText() const
933 {
934 wxString text;
935 wxHelpProvider *helpProvider = wxHelpProvider::Get();
936 if ( helpProvider )
937 {
938 text = helpProvider->GetHelp(this);
939 }
940
941 return text;
942 }
943
944 // show help for this window
945 void wxWindowBase::OnHelp(wxHelpEvent& event)
946 {
947 wxHelpProvider *helpProvider = wxHelpProvider::Get();
948 if ( helpProvider )
949 {
950 if ( helpProvider->ShowHelp(this) )
951 {
952 // skip the event.Skip() below
953 return;
954 }
955 }
956
957 event.Skip();
958 }
959
960 #endif // wxUSE_HELP
961
962 // ----------------------------------------------------------------------------
963 // tooltips
964 // ----------------------------------------------------------------------------
965
966 #if wxUSE_TOOLTIPS
967
968 void wxWindowBase::SetToolTip( const wxString &tip )
969 {
970 // don't create the new tooltip if we already have one
971 if ( m_tooltip )
972 {
973 m_tooltip->SetTip( tip );
974 }
975 else
976 {
977 SetToolTip( new wxToolTip( tip ) );
978 }
979
980 // setting empty tooltip text does not remove the tooltip any more - use
981 // SetToolTip((wxToolTip *)NULL) for this
982 }
983
984 void wxWindowBase::DoSetToolTip(wxToolTip *tooltip)
985 {
986 if ( m_tooltip )
987 delete m_tooltip;
988
989 m_tooltip = tooltip;
990 }
991
992 #endif // wxUSE_TOOLTIPS
993
994 // ----------------------------------------------------------------------------
995 // constraints and sizers
996 // ----------------------------------------------------------------------------
997
998 #if wxUSE_CONSTRAINTS
999
1000 void wxWindowBase::SetConstraints( wxLayoutConstraints *constraints )
1001 {
1002 if ( m_constraints )
1003 {
1004 UnsetConstraints(m_constraints);
1005 delete m_constraints;
1006 }
1007 m_constraints = constraints;
1008 if ( m_constraints )
1009 {
1010 // Make sure other windows know they're part of a 'meaningful relationship'
1011 if ( m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this) )
1012 m_constraints->left.GetOtherWindow()->AddConstraintReference(this);
1013 if ( m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this) )
1014 m_constraints->top.GetOtherWindow()->AddConstraintReference(this);
1015 if ( m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this) )
1016 m_constraints->right.GetOtherWindow()->AddConstraintReference(this);
1017 if ( m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this) )
1018 m_constraints->bottom.GetOtherWindow()->AddConstraintReference(this);
1019 if ( m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this) )
1020 m_constraints->width.GetOtherWindow()->AddConstraintReference(this);
1021 if ( m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this) )
1022 m_constraints->height.GetOtherWindow()->AddConstraintReference(this);
1023 if ( m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this) )
1024 m_constraints->centreX.GetOtherWindow()->AddConstraintReference(this);
1025 if ( m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this) )
1026 m_constraints->centreY.GetOtherWindow()->AddConstraintReference(this);
1027 }
1028 }
1029
1030 // This removes any dangling pointers to this window in other windows'
1031 // constraintsInvolvedIn lists.
1032 void wxWindowBase::UnsetConstraints(wxLayoutConstraints *c)
1033 {
1034 if ( c )
1035 {
1036 if ( c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this) )
1037 c->left.GetOtherWindow()->RemoveConstraintReference(this);
1038 if ( c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this) )
1039 c->top.GetOtherWindow()->RemoveConstraintReference(this);
1040 if ( c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this) )
1041 c->right.GetOtherWindow()->RemoveConstraintReference(this);
1042 if ( c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this) )
1043 c->bottom.GetOtherWindow()->RemoveConstraintReference(this);
1044 if ( c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this) )
1045 c->width.GetOtherWindow()->RemoveConstraintReference(this);
1046 if ( c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this) )
1047 c->height.GetOtherWindow()->RemoveConstraintReference(this);
1048 if ( c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this) )
1049 c->centreX.GetOtherWindow()->RemoveConstraintReference(this);
1050 if ( c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this) )
1051 c->centreY.GetOtherWindow()->RemoveConstraintReference(this);
1052 }
1053 }
1054
1055 // Back-pointer to other windows we're involved with, so if we delete this
1056 // window, we must delete any constraints we're involved with.
1057 void wxWindowBase::AddConstraintReference(wxWindowBase *otherWin)
1058 {
1059 if ( !m_constraintsInvolvedIn )
1060 m_constraintsInvolvedIn = new wxWindowList;
1061 if ( !m_constraintsInvolvedIn->Find(otherWin) )
1062 m_constraintsInvolvedIn->Append(otherWin);
1063 }
1064
1065 // REMOVE back-pointer to other windows we're involved with.
1066 void wxWindowBase::RemoveConstraintReference(wxWindowBase *otherWin)
1067 {
1068 if ( m_constraintsInvolvedIn )
1069 m_constraintsInvolvedIn->DeleteObject(otherWin);
1070 }
1071
1072 // Reset any constraints that mention this window
1073 void wxWindowBase::DeleteRelatedConstraints()
1074 {
1075 if ( m_constraintsInvolvedIn )
1076 {
1077 wxWindowList::Node *node = m_constraintsInvolvedIn->GetFirst();
1078 while (node)
1079 {
1080 wxWindow *win = node->GetData();
1081 wxLayoutConstraints *constr = win->GetConstraints();
1082
1083 // Reset any constraints involving this window
1084 if ( constr )
1085 {
1086 constr->left.ResetIfWin(this);
1087 constr->top.ResetIfWin(this);
1088 constr->right.ResetIfWin(this);
1089 constr->bottom.ResetIfWin(this);
1090 constr->width.ResetIfWin(this);
1091 constr->height.ResetIfWin(this);
1092 constr->centreX.ResetIfWin(this);
1093 constr->centreY.ResetIfWin(this);
1094 }
1095
1096 wxWindowList::Node *next = node->GetNext();
1097 delete node;
1098 node = next;
1099 }
1100
1101 delete m_constraintsInvolvedIn;
1102 m_constraintsInvolvedIn = (wxWindowList *) NULL;
1103 }
1104 }
1105
1106 void wxWindowBase::SetSizer(wxSizer *sizer)
1107 {
1108 if (m_windowSizer) delete m_windowSizer;
1109
1110 m_windowSizer = sizer;
1111 }
1112
1113 bool wxWindowBase::Layout()
1114 {
1115 // If there is a sizer, use it instead of the constraints
1116 if ( GetSizer() )
1117 {
1118 int w, h;
1119 GetClientSize(&w, &h);
1120
1121 GetSizer()->SetDimension( 0, 0, w, h );
1122 }
1123 else
1124 {
1125 wxLayoutConstraints *constr = GetConstraints();
1126 bool wasOk = constr && constr->AreSatisfied();
1127
1128 ResetConstraints(); // Mark all constraints as unevaluated
1129
1130 // if we're a top level panel (i.e. our parent is frame/dialog), our
1131 // own constraints will never be satisfied any more unless we do it
1132 // here
1133 if ( wasOk )
1134 {
1135 int noChanges = 1;
1136 while ( noChanges > 0 )
1137 {
1138 constr->SatisfyConstraints(this, &noChanges);
1139 }
1140 }
1141
1142 DoPhase(1); // Layout children
1143 DoPhase(2); // Layout grand children
1144 SetConstraintSizes(); // Recursively set the real window sizes
1145 }
1146
1147 return TRUE;
1148 }
1149
1150
1151 // Do a phase of evaluating constraints: the default behaviour. wxSizers may
1152 // do a similar thing, but also impose their own 'constraints' and order the
1153 // evaluation differently.
1154 bool wxWindowBase::LayoutPhase1(int *noChanges)
1155 {
1156 wxLayoutConstraints *constr = GetConstraints();
1157 if ( constr )
1158 {
1159 return constr->SatisfyConstraints(this, noChanges);
1160 }
1161 else
1162 return TRUE;
1163 }
1164
1165 bool wxWindowBase::LayoutPhase2(int *noChanges)
1166 {
1167 *noChanges = 0;
1168
1169 // Layout children
1170 DoPhase(1);
1171 DoPhase(2);
1172 return TRUE;
1173 }
1174
1175 // Do a phase of evaluating child constraints
1176 bool wxWindowBase::DoPhase(int phase)
1177 {
1178 int noIterations = 0;
1179 int maxIterations = 500;
1180 int noChanges = 1;
1181 int noFailures = 0;
1182 wxWindowList succeeded;
1183 while ((noChanges > 0) && (noIterations < maxIterations))
1184 {
1185 noChanges = 0;
1186 noFailures = 0;
1187 wxWindowList::Node *node = GetChildren().GetFirst();
1188 while (node)
1189 {
1190 wxWindow *child = node->GetData();
1191 if ( !child->IsTopLevel() )
1192 {
1193 wxLayoutConstraints *constr = child->GetConstraints();
1194 if ( constr )
1195 {
1196 if ( !succeeded.Find(child) )
1197 {
1198 int tempNoChanges = 0;
1199 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
1200 noChanges += tempNoChanges;
1201 if ( success )
1202 {
1203 succeeded.Append(child);
1204 }
1205 }
1206 }
1207 }
1208 node = node->GetNext();
1209 }
1210
1211 noIterations++;
1212 }
1213
1214 return TRUE;
1215 }
1216
1217 void wxWindowBase::ResetConstraints()
1218 {
1219 wxLayoutConstraints *constr = GetConstraints();
1220 if ( constr )
1221 {
1222 constr->left.SetDone(FALSE);
1223 constr->top.SetDone(FALSE);
1224 constr->right.SetDone(FALSE);
1225 constr->bottom.SetDone(FALSE);
1226 constr->width.SetDone(FALSE);
1227 constr->height.SetDone(FALSE);
1228 constr->centreX.SetDone(FALSE);
1229 constr->centreY.SetDone(FALSE);
1230 }
1231
1232 wxWindowList::Node *node = GetChildren().GetFirst();
1233 while (node)
1234 {
1235 wxWindow *win = node->GetData();
1236 if ( !win->IsTopLevel() )
1237 win->ResetConstraints();
1238 node = node->GetNext();
1239 }
1240 }
1241
1242 // Need to distinguish between setting the 'fake' size for windows and sizers,
1243 // and setting the real values.
1244 void wxWindowBase::SetConstraintSizes(bool recurse)
1245 {
1246 wxLayoutConstraints *constr = GetConstraints();
1247 if ( constr && constr->AreSatisfied() )
1248 {
1249 int x = constr->left.GetValue();
1250 int y = constr->top.GetValue();
1251 int w = constr->width.GetValue();
1252 int h = constr->height.GetValue();
1253
1254 if ( (constr->width.GetRelationship() != wxAsIs ) ||
1255 (constr->height.GetRelationship() != wxAsIs) )
1256 {
1257 SetSize(x, y, w, h);
1258 }
1259 else
1260 {
1261 // If we don't want to resize this window, just move it...
1262 Move(x, y);
1263 }
1264 }
1265 else if ( constr )
1266 {
1267 wxLogDebug(wxT("Constraints not satisfied for %s named '%s'."),
1268 GetClassInfo()->GetClassName(),
1269 GetName().c_str());
1270 }
1271
1272 if ( recurse )
1273 {
1274 wxWindowList::Node *node = GetChildren().GetFirst();
1275 while (node)
1276 {
1277 wxWindow *win = node->GetData();
1278 if ( !win->IsTopLevel() && win->GetConstraints() )
1279 win->SetConstraintSizes();
1280 node = node->GetNext();
1281 }
1282 }
1283 }
1284
1285 // Only set the size/position of the constraint (if any)
1286 void wxWindowBase::SetSizeConstraint(int x, int y, int w, int h)
1287 {
1288 wxLayoutConstraints *constr = GetConstraints();
1289 if ( constr )
1290 {
1291 if ( x != -1 )
1292 {
1293 constr->left.SetValue(x);
1294 constr->left.SetDone(TRUE);
1295 }
1296 if ( y != -1 )
1297 {
1298 constr->top.SetValue(y);
1299 constr->top.SetDone(TRUE);
1300 }
1301 if ( w != -1 )
1302 {
1303 constr->width.SetValue(w);
1304 constr->width.SetDone(TRUE);
1305 }
1306 if ( h != -1 )
1307 {
1308 constr->height.SetValue(h);
1309 constr->height.SetDone(TRUE);
1310 }
1311 }
1312 }
1313
1314 void wxWindowBase::MoveConstraint(int x, int y)
1315 {
1316 wxLayoutConstraints *constr = GetConstraints();
1317 if ( constr )
1318 {
1319 if ( x != -1 )
1320 {
1321 constr->left.SetValue(x);
1322 constr->left.SetDone(TRUE);
1323 }
1324 if ( y != -1 )
1325 {
1326 constr->top.SetValue(y);
1327 constr->top.SetDone(TRUE);
1328 }
1329 }
1330 }
1331
1332 void wxWindowBase::GetSizeConstraint(int *w, int *h) const
1333 {
1334 wxLayoutConstraints *constr = GetConstraints();
1335 if ( constr )
1336 {
1337 *w = constr->width.GetValue();
1338 *h = constr->height.GetValue();
1339 }
1340 else
1341 GetSize(w, h);
1342 }
1343
1344 void wxWindowBase::GetClientSizeConstraint(int *w, int *h) const
1345 {
1346 wxLayoutConstraints *constr = GetConstraints();
1347 if ( constr )
1348 {
1349 *w = constr->width.GetValue();
1350 *h = constr->height.GetValue();
1351 }
1352 else
1353 GetClientSize(w, h);
1354 }
1355
1356 void wxWindowBase::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
1357 {
1358 // don't do it for the dialogs/frames - they float independently of their
1359 // parent
1360 if ( !IsTopLevel() )
1361 {
1362 wxWindow *parent = GetParent();
1363 if ( !(sizeFlags & wxSIZE_NO_ADJUSTMENTS) && parent )
1364 {
1365 wxPoint pt(parent->GetClientAreaOrigin());
1366 x += pt.x;
1367 y += pt.y;
1368 }
1369 }
1370 }
1371
1372
1373 void wxWindowBase::GetPositionConstraint(int *x, int *y) const
1374 {
1375 wxLayoutConstraints *constr = GetConstraints();
1376 if ( constr )
1377 {
1378 *x = constr->left.GetValue();
1379 *y = constr->top.GetValue();
1380 }
1381 else
1382 GetPosition(x, y);
1383 }
1384
1385 #endif // wxUSE_CONSTRAINTS
1386
1387 // ----------------------------------------------------------------------------
1388 // do Update UI processing for child controls
1389 // ----------------------------------------------------------------------------
1390
1391 // TODO: should this be implemented for the child window rather
1392 // than the parent? Then you can override it e.g. for wxCheckBox
1393 // to do the Right Thing rather than having to assume a fixed number
1394 // of control classes.
1395 void wxWindowBase::UpdateWindowUI()
1396 {
1397 #if wxUSE_CONTROLS
1398 wxUpdateUIEvent event(GetId());
1399 event.m_eventObject = this;
1400
1401 if ( GetEventHandler()->ProcessEvent(event) )
1402 {
1403 if ( event.GetSetEnabled() )
1404 Enable(event.GetEnabled());
1405
1406 if ( event.GetSetText() )
1407 {
1408 wxControl *control = wxDynamicCastThis(wxControl);
1409 if ( control )
1410 {
1411 #if wxUSE_TEXTCTRL
1412 wxTextCtrl *text = wxDynamicCast(control, wxTextCtrl);
1413 if ( text )
1414 text->SetValue(event.GetText());
1415 else
1416 #endif // wxUSE_TEXTCTRL
1417 control->SetLabel(event.GetText());
1418 }
1419 }
1420
1421 #if wxUSE_CHECKBOX
1422 wxCheckBox *checkbox = wxDynamicCastThis(wxCheckBox);
1423 if ( checkbox )
1424 {
1425 if ( event.GetSetChecked() )
1426 checkbox->SetValue(event.GetChecked());
1427 }
1428 #endif // wxUSE_CHECKBOX
1429
1430 #if wxUSE_RADIOBTN
1431 wxRadioButton *radiobtn = wxDynamicCastThis(wxRadioButton);
1432 if ( radiobtn )
1433 {
1434 if ( event.GetSetChecked() )
1435 radiobtn->SetValue(event.GetChecked());
1436 }
1437 #endif // wxUSE_RADIOBTN
1438 }
1439 #endif // wxUSE_CONTROLS
1440 }
1441
1442 // ----------------------------------------------------------------------------
1443 // dialog units translations
1444 // ----------------------------------------------------------------------------
1445
1446 wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt)
1447 {
1448 int charWidth = GetCharWidth();
1449 int charHeight = GetCharHeight();
1450 wxPoint pt2(-1, -1);
1451 if (pt.x != -1)
1452 pt2.x = (int) ((pt.x * 4) / charWidth) ;
1453 if (pt.y != -1)
1454 pt2.y = (int) ((pt.y * 8) / charHeight) ;
1455
1456 return pt2;
1457 }
1458
1459 wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt)
1460 {
1461 int charWidth = GetCharWidth();
1462 int charHeight = GetCharHeight();
1463 wxPoint pt2(-1, -1);
1464 if (pt.x != -1)
1465 pt2.x = (int) ((pt.x * charWidth) / 4) ;
1466 if (pt.y != -1)
1467 pt2.y = (int) ((pt.y * charHeight) / 8) ;
1468
1469 return pt2;
1470 }
1471
1472 // ----------------------------------------------------------------------------
1473 // event handlers
1474 // ----------------------------------------------------------------------------
1475
1476 // propagate the colour change event to the subwindows
1477 void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
1478 {
1479 wxWindowList::Node *node = GetChildren().GetFirst();
1480 while ( node )
1481 {
1482 // Only propagate to non-top-level windows
1483 wxWindow *win = node->GetData();
1484 if ( !win->IsTopLevel() )
1485 {
1486 wxSysColourChangedEvent event2;
1487 event.m_eventObject = win;
1488 win->GetEventHandler()->ProcessEvent(event2);
1489 }
1490
1491 node = node->GetNext();
1492 }
1493 }
1494
1495 // the default action is to populate dialog with data when it's created
1496 void wxWindowBase::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
1497 {
1498 TransferDataToWindow();
1499 }
1500
1501 // process Ctrl-Alt-mclick
1502 void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
1503 {
1504 #if wxUSE_MSGDLG
1505 if ( event.ControlDown() && event.AltDown() )
1506 {
1507 // don't translate these strings
1508 wxString port;
1509 switch ( wxGetOsVersion() )
1510 {
1511 case wxMOTIF_X: port = _T("Motif"); break;
1512 case wxMAC:
1513 case wxMAC_DARWIN: port = _T("Mac"); break;
1514 case wxBEOS: port = _T("BeOS"); break;
1515 case wxGTK:
1516 case wxGTK_WIN32:
1517 case wxGTK_OS2:
1518 case wxGTK_BEOS: port = _T("GTK"); break;
1519 case wxWINDOWS:
1520 case wxPENWINDOWS:
1521 case wxWINDOWS_NT:
1522 case wxWIN32S:
1523 case wxWIN95:
1524 case wxWIN386: port = _T("MS Windows"); break;
1525 case wxMGL_UNIX:
1526 case wxMGL_X:
1527 case wxMGL_WIN32:
1528 case wxMGL_OS2: port = _T("MGL"); break;
1529 case wxWINDOWS_OS2:
1530 case wxOS2_PM: port = _T("OS/2"); break;
1531 default: port = _T("unknown"); break;
1532 }
1533
1534 wxMessageBox(wxString::Format(
1535 _T(
1536 " wxWindows Library (%s port)\nVersion %u.%u.%u, compiled at %s %s\n Copyright (c) 1995-2001 wxWindows team"
1537 ),
1538 port.c_str(),
1539 wxMAJOR_VERSION,
1540 wxMINOR_VERSION,
1541 wxRELEASE_NUMBER,
1542 __DATE__,
1543 __TIME__
1544 ),
1545 _T("wxWindows information"),
1546 wxICON_INFORMATION | wxOK,
1547 (wxWindow *)this);
1548 }
1549 else
1550 #endif // wxUSE_MSGDLG
1551 {
1552 event.Skip();
1553 }
1554 }
1555
1556 // ----------------------------------------------------------------------------
1557 // list classes implementation
1558 // ----------------------------------------------------------------------------
1559
1560 void wxWindowListNode::DeleteData()
1561 {
1562 delete (wxWindow *)GetData();
1563 }
1564
1565 // ----------------------------------------------------------------------------
1566 // borders
1567 // ----------------------------------------------------------------------------
1568
1569 wxBorder wxWindowBase::GetBorder() const
1570 {
1571 wxBorder border = (wxBorder)(m_windowStyle & wxBORDER_MASK);
1572 if ( border == wxBORDER_DEFAULT )
1573 {
1574 border = GetDefaultBorder();
1575 }
1576
1577 return border;
1578 }
1579
1580 wxBorder wxWindowBase::GetDefaultBorder() const
1581 {
1582 return wxBORDER_NONE;
1583 }
1584
1585 // ----------------------------------------------------------------------------
1586 // hit testing
1587 // ----------------------------------------------------------------------------
1588
1589 wxHitTest wxWindowBase::DoHitTest(wxCoord x, wxCoord y) const
1590 {
1591 // here we just check if the point is inside the window or not
1592
1593 // check the top and left border first
1594 bool outside = x < 0 || y < 0;
1595 if ( !outside )
1596 {
1597 // check the right and bottom borders too
1598 wxSize size = GetSize();
1599 outside = x >= size.x || y >= size.y;
1600 }
1601
1602 return outside ? wxHT_WINDOW_OUTSIDE : wxHT_WINDOW_INSIDE;
1603 }
1604