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