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