]> git.saurik.com Git - wxWidgets.git/blame - src/common/wincmn.cpp
corrected constness
[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"
1e6feb95 38 #include "wx/control.h"
f03fc89f
VZ
39 #include "wx/checkbox.h"
40 #include "wx/radiobut.h"
26bf1ce0 41 #include "wx/textctrl.h"
f03fc89f
VZ
42 #include "wx/settings.h"
43 #include "wx/dialog.h"
a02dc3e3 44 #include "wx/msgdlg.h"
a37a5a73 45 #include "wx/statusbr.h"
f03fc89f
VZ
46#endif //WX_PRECOMP
47
48#if wxUSE_CONSTRAINTS
49 #include "wx/layout.h"
3417c2cd 50 #include "wx/sizer.h"
f03fc89f
VZ
51#endif // wxUSE_CONSTRAINTS
52
53#if wxUSE_DRAG_AND_DROP
54 #include "wx/dnd.h"
55#endif // wxUSE_DRAG_AND_DROP
56
bd83cb56
VZ
57#if wxUSE_HELP
58 #include "wx/cshelp.h"
59#endif // wxUSE_HELP
60
f03fc89f
VZ
61#if wxUSE_TOOLTIPS
62 #include "wx/tooltip.h"
63#endif // wxUSE_TOOLTIPS
64
789295bf
VZ
65#if wxUSE_CARET
66 #include "wx/caret.h"
67#endif // wxUSE_CARET
68
f03fc89f
VZ
69// ----------------------------------------------------------------------------
70// static data
71// ----------------------------------------------------------------------------
72
42e69d6b 73int wxWindowBase::ms_lastControlId = -200;
f03fc89f
VZ
74
75IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
76
77// ----------------------------------------------------------------------------
78// event table
79// ----------------------------------------------------------------------------
80
81BEGIN_EVENT_TABLE(wxWindowBase, wxEvtHandler)
82 EVT_SYS_COLOUR_CHANGED(wxWindowBase::OnSysColourChanged)
83 EVT_INIT_DIALOG(wxWindowBase::OnInitDialog)
a02dc3e3 84 EVT_MIDDLE_DOWN(wxWindowBase::OnMiddleClick)
bd83cb56
VZ
85
86#if wxUSE_HELP
87 EVT_HELP(-1, wxWindowBase::OnHelp)
88#endif // wxUSE_HELP
89
f03fc89f
VZ
90END_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
101void wxWindowBase::InitBase()
102{
103 // no window yet, no parent nor children
f03fc89f
VZ
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
f03fc89f
VZ
118 // the default event handler is just this window
119 m_eventHandler = this;
120
88ac883a 121#if wxUSE_VALIDATORS
f03fc89f
VZ
122 // no validator
123 m_windowValidator = (wxValidator *) NULL;
88ac883a 124#endif // wxUSE_VALIDATORS
f03fc89f
VZ
125
126 // use the system default colours
807a903e 127 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE);
f6e4e9ea
JS
128 m_foregroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT);
129
8bf30fe9
VZ
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__
807a903e 134 m_font = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
8bf30fe9 135#endif // __WXMSW__
807a903e 136
f03fc89f 137 // no style bits
d80cd92a 138 m_exStyle =
f03fc89f
VZ
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;
f03fc89f
VZ
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
789295bf
VZ
160
161#if wxUSE_CARET
162 m_caret = (wxCaret *)NULL;
163#endif // wxUSE_CARET
a2d93e73
JS
164
165 // Whether we're using the current theme for this window (wxGTK only for now)
166 m_themeEnabled = FALSE;
f03fc89f
VZ
167}
168
169// common part of window creation process
170bool wxWindowBase::CreateBase(wxWindowBase *parent,
171 wxWindowID id,
74e3313b
VZ
172 const wxPoint& WXUNUSED(pos),
173 const wxSize& WXUNUSED(size),
f03fc89f 174 long style,
8d99be5f 175 const wxValidator& validator,
f03fc89f
VZ
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)
223d09f6 181 wxASSERT_MSG( m_isWindow, wxT("Init() must have been called before!") );
f03fc89f
VZ
182
183 // generate a new id if the user doesn't care about it
69418a8e 184 m_windowId = id == -1 ? NewControlId() : id;
f03fc89f
VZ
185
186 SetName(name);
187 SetWindowStyleFlag(style);
188 SetParent(parent);
674ac8b9
VZ
189
190#if wxUSE_VALIDATORS
8d99be5f 191 SetValidator(validator);
674ac8b9 192#endif // wxUSE_VALIDATORS
f03fc89f 193
8ae6ce07
VZ
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
f03fc89f
VZ
202 return TRUE;
203}
204
205// ----------------------------------------------------------------------------
206// destruction
207// ----------------------------------------------------------------------------
208
209// common clean up
210wxWindowBase::~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);
a23fd0e1 222
223d09f6 223 wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );
f03fc89f 224
789295bf
VZ
225#if wxUSE_CARET
226 if ( m_caret )
227 delete m_caret;
228#endif // wxUSE_CARET
229
88ac883a 230#if wxUSE_VALIDATORS
f03fc89f
VZ
231 if ( m_windowValidator )
232 delete m_windowValidator;
88ac883a 233#endif // wxUSE_VALIDATORS
f03fc89f 234
f03fc89f
VZ
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
f03fc89f
VZ
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
b0ee47ff
VZ
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 }
f03fc89f
VZ
269}
270
271bool wxWindowBase::Destroy()
272{
273 delete this;
274
275 return TRUE;
276}
277
278bool 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
292bool wxWindowBase::DestroyChildren()
293{
294 wxWindowList::Node *node;
a23fd0e1 295 for ( ;; )
f03fc89f 296 {
a23fd0e1
VZ
297 // we iterate until the list becomes empty
298 node = GetChildren().GetFirst();
299 if ( !node )
300 break;
301
f03fc89f 302 wxWindow *child = node->GetData();
a23fd0e1 303
223d09f6 304 wxASSERT_MSG( child, wxT("children list contains empty nodes") );
a23fd0e1 305
1a77875b 306 child->Show(FALSE);
eb082a08 307 delete child;
a23fd0e1
VZ
308
309 wxASSERT_MSG( !GetChildren().Find(child),
223d09f6 310 wxT("child didn't remove itself using RemoveChild()") );
f03fc89f
VZ
311 }
312
313 return TRUE;
314}
315
316// ----------------------------------------------------------------------------
f68586e5 317// size/position related methods
f03fc89f
VZ
318// ----------------------------------------------------------------------------
319
320// centre the window with respect to its parent in either (or both) directions
321void wxWindowBase::Centre(int direction)
322{
f6bcfd97
BP
323 // the position/size of the parent window or of the entire screen
324 wxPoint posParent;
f03fc89f
VZ
325 int widthParent, heightParent;
326
f6bcfd97
BP
327 wxWindow *parent = NULL;
328
329 if ( !(direction & wxCENTRE_ON_SCREEN) )
f03fc89f 330 {
f6bcfd97
BP
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 }
f03fc89f 349 }
10fcf31a
VZ
350
351 if ( direction & wxCENTRE_ON_SCREEN )
f03fc89f
VZ
352 {
353 // centre with respect to the whole screen
354 wxDisplaySize(&widthParent, &heightParent);
355 }
10fcf31a
VZ
356 else
357 {
f6bcfd97
BP
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 }
10fcf31a 371 }
f03fc89f
VZ
372
373 int width, height;
374 GetSize(&width, &height);
375
c39eda94
VZ
376 int xNew = -1,
377 yNew = -1;
f03fc89f
VZ
378
379 if ( direction & wxHORIZONTAL )
c39eda94 380 xNew = (widthParent - width)/2;
f03fc89f
VZ
381
382 if ( direction & wxVERTICAL )
c39eda94 383 yNew = (heightParent - height)/2;
f03fc89f 384
f6bcfd97
BP
385 xNew += posParent.x;
386 yNew += posParent.y;
7631a292 387
ef397583
GT
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
0fff366e
VZ
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)
db89aa76 414 SetSize(xNew, yNew, width, height, wxSIZE_ALLOW_MINUS_ONE);
7631a292
RD
415}
416
f03fc89f
VZ
417// fits the window around the children
418void wxWindowBase::Fit()
419{
f68586e5
VZ
420 if ( GetChildren().GetCount() > 0 )
421 {
ba81034d
VZ
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);
f68586e5
VZ
430 }
431 //else: do nothing if we have no children
432}
f03fc89f 433
f68586e5
VZ
434// return the size best suited for the current window
435wxSize wxWindowBase::DoGetBestSize() const
436{
437 if ( GetChildren().GetCount() > 0 )
f03fc89f 438 {
f68586e5
VZ
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() )
42e69d6b 446 {
f68586e5 447 wxWindow *win = node->GetData();
1e6feb95
VZ
448 if ( win->IsTopLevel()
449#if wxUSE_STATUSBAR
450 || wxDynamicCast(win, wxStatusBar)
451#endif // wxUSE_STATUSBAR
452 )
f68586e5
VZ
453 {
454 // dialogs and frames lie in different top level windows -
7d9fd004
VZ
455 // don't deal with them here; as for the status bars, they
456 // don't lie in the client area at all
f68586e5
VZ
457 continue;
458 }
459
460 int wx, wy, ww, wh;
461 win->GetPosition(&wx, &wy);
3f5513f5
VZ
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
f68586e5
VZ
470 win->GetSize(&ww, &wh);
471 if ( wx + ww > maxX )
472 maxX = wx + ww;
473 if ( wy + wh > maxY )
474 maxY = wy + wh;
42e69d6b
VZ
475 }
476
ba81034d 477 return wxSize(maxX, maxY);
f68586e5
VZ
478 }
479 else
480 {
481 // for a generic window there is no natural best size - just use the
482 // current one
483 return GetSize();
f03fc89f 484 }
f03fc89f
VZ
485}
486
1e6feb95
VZ
487// by default the origin is not shifted
488wxPoint wxWindowBase::GetClientAreaOrigin() const
489{
490 return wxPoint(0, 0);
491}
492
f03fc89f 493// set the min/max size of the window
f03fc89f
VZ
494void 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
508bool 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
522bool 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}
34636400
VZ
535// ----------------------------------------------------------------------------
536// RTTI
537// ----------------------------------------------------------------------------
538
539bool wxWindowBase::IsTopLevel() const
540{
8487f887 541 return FALSE;
34636400 542}
f03fc89f
VZ
543
544// ----------------------------------------------------------------------------
545// reparenting the window
546// ----------------------------------------------------------------------------
547
548void wxWindowBase::AddChild(wxWindowBase *child)
549{
223d09f6 550 wxCHECK_RET( child, wxT("can't add a NULL child") );
f03fc89f 551
f6bcfd97
BP
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
f03fc89f
VZ
557 GetChildren().Append(child);
558 child->SetParent(this);
559}
560
561void wxWindowBase::RemoveChild(wxWindowBase *child)
562{
223d09f6 563 wxCHECK_RET( child, wxT("can't remove a NULL child") );
f03fc89f
VZ
564
565 GetChildren().DeleteObject(child);
566 child->SetParent((wxWindow *)NULL);
567}
439b3bf1 568
f03fc89f
VZ
569bool 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
605void wxWindowBase::PushEventHandler(wxEvtHandler *handler)
606{
607 handler->SetNextHandler(GetEventHandler());
608 SetEventHandler(handler);
609}
610
611wxEvtHandler *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
633bool wxWindowBase::SetBackgroundColour( const wxColour &colour )
634{
635 if ( !colour.Ok() || (colour == m_backgroundColour) )
636 return FALSE;
637
638 m_backgroundColour = colour;
639
23895080
VZ
640 m_hasBgCol = TRUE;
641
f03fc89f
VZ
642 return TRUE;
643}
644
645bool wxWindowBase::SetForegroundColour( const wxColour &colour )
646{
647 if ( !colour.Ok() || (colour == m_foregroundColour) )
648 return FALSE;
649
650 m_foregroundColour = colour;
651
23895080
VZ
652 m_hasFgCol = TRUE;
653
f03fc89f
VZ
654 return TRUE;
655}
656
657bool wxWindowBase::SetCursor(const wxCursor& cursor)
658{
8a9c2246
VZ
659 // setting an invalid cursor is ok, it means that we don't have any special
660 // cursor
13588544 661 if ( m_cursor == cursor )
f03fc89f
VZ
662 {
663 // no change
664 return FALSE;
665 }
666
8a9c2246 667 m_cursor = cursor;
f03fc89f
VZ
668
669 return TRUE;
670}
671
672bool 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
8bf30fe9 677 if ( fontOk == m_font )
f03fc89f
VZ
678 {
679 // no change
680 return FALSE;
681 }
682
683 m_font = fontOk;
684
23895080
VZ
685 m_hasFont = TRUE;
686
f03fc89f
VZ
687 return TRUE;
688}
689
789295bf
VZ
690#if wxUSE_CARET
691void 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,
223d09f6 703 wxT("caret should be created associated to this window") );
789295bf
VZ
704 }
705}
706#endif // wxUSE_CARET
707
88ac883a 708#if wxUSE_VALIDATORS
f03fc89f
VZ
709// ----------------------------------------------------------------------------
710// validators
711// ----------------------------------------------------------------------------
712
713void 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}
88ac883a 723#endif // wxUSE_VALIDATORS
f03fc89f
VZ
724
725// ----------------------------------------------------------------------------
1e6feb95 726// update region stuff
f03fc89f
VZ
727// ----------------------------------------------------------------------------
728
1e6feb95
VZ
729wxRect 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
f03fc89f
VZ
741bool wxWindowBase::IsExposed(int x, int y) const
742{
743 return m_updateRegion.Contains(x, y) != wxOutRegion;
744}
745
746bool 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
755wxWindow *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
771wxWindow *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
34636400 791void wxWindowBase::MakeModal(bool modal)
f03fc89f 792{
34636400
VZ
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 }
f03fc89f
VZ
806}
807
808bool wxWindowBase::Validate()
809{
88ac883a 810#if wxUSE_VALIDATORS
d80cd92a
VZ
811 bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
812
f03fc89f
VZ
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();
dcd6b914 818 if ( validator && !validator->Validate((wxWindow *)this) )
f03fc89f
VZ
819 {
820 return FALSE;
821 }
d80cd92a
VZ
822
823 if ( recurse && !child->Validate() )
824 {
825 return FALSE;
826 }
f03fc89f 827 }
88ac883a 828#endif // wxUSE_VALIDATORS
f03fc89f
VZ
829
830 return TRUE;
831}
832
833bool wxWindowBase::TransferDataToWindow()
834{
88ac883a 835#if wxUSE_VALIDATORS
d80cd92a
VZ
836 bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
837
f03fc89f
VZ
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 {
d80cd92a
VZ
845 wxLogWarning(_("Could not transfer data to window"));
846 wxLog::FlushActive();
f03fc89f
VZ
847
848 return FALSE;
849 }
d80cd92a
VZ
850
851 if ( recurse )
852 {
a58a12e9 853 if ( !child->TransferDataToWindow() )
d80cd92a
VZ
854 {
855 // warning already given
856 return FALSE;
857 }
858 }
f03fc89f 859 }
88ac883a 860#endif // wxUSE_VALIDATORS
f03fc89f
VZ
861
862 return TRUE;
863}
864
865bool wxWindowBase::TransferDataFromWindow()
866{
88ac883a 867#if wxUSE_VALIDATORS
d80cd92a
VZ
868 bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
869
f03fc89f
VZ
870 wxWindowList::Node *node;
871 for ( node = m_children.GetFirst(); node; node = node->GetNext() )
872 {
873 wxWindow *child = node->GetData();
d80cd92a
VZ
874 wxValidator *validator = child->GetValidator();
875 if ( validator && !validator->TransferFromWindow() )
f03fc89f 876 {
d80cd92a
VZ
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
f03fc89f
VZ
880 return FALSE;
881 }
d80cd92a
VZ
882
883 if ( recurse )
884 {
a58a12e9 885 if ( !child->TransferDataFromWindow() )
d80cd92a
VZ
886 {
887 // warning already given
888 return FALSE;
889 }
890 }
f03fc89f 891 }
88ac883a 892#endif // wxUSE_VALIDATORS
f03fc89f
VZ
893
894 return TRUE;
895}
896
897void wxWindowBase::InitDialog()
898{
899 wxInitDialogEvent event(GetId());
900 event.SetEventObject( this );
901 GetEventHandler()->ProcessEvent(event);
902}
903
904// ----------------------------------------------------------------------------
bd83cb56
VZ
905// context-sensitive help support
906// ----------------------------------------------------------------------------
907
908#if wxUSE_HELP
909
910// associate this help text with this window
911void 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
922void 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)
932wxString 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
945void 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// ----------------------------------------------------------------------------
f03fc89f
VZ
963// tooltips
964// ----------------------------------------------------------------------------
965
966#if wxUSE_TOOLTIPS
967
968void 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
984void 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
1000void 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.
1032void 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.
1057void 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.
1066void wxWindowBase::RemoveConstraintReference(wxWindowBase *otherWin)
1067{
1068 if ( m_constraintsInvolvedIn )
1069 m_constraintsInvolvedIn->DeleteObject(otherWin);
1070}
1071
1072// Reset any constraints that mention this window
1073void 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
1106void wxWindowBase::SetSizer(wxSizer *sizer)
1107{
3417c2cd
RR
1108 if (m_windowSizer) delete m_windowSizer;
1109
f03fc89f 1110 m_windowSizer = sizer;
f03fc89f
VZ
1111}
1112
1113bool wxWindowBase::Layout()
1114{
3417c2cd 1115 // If there is a sizer, use it instead of the constraints
f03fc89f
VZ
1116 if ( GetSizer() )
1117 {
f1df0927
VZ
1118 int w, h;
1119 GetClientSize(&w, &h);
1120
3417c2cd 1121 GetSizer()->SetDimension( 0, 0, w, h );
f03fc89f 1122 }
f1df0927 1123 else
f03fc89f 1124 {
4b7f2165
VZ
1125 wxLayoutConstraints *constr = GetConstraints();
1126 bool wasOk = constr && constr->AreSatisfied();
1127
f1df0927 1128 ResetConstraints(); // Mark all constraints as unevaluated
4b7f2165
VZ
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
f1df0927 1144 SetConstraintSizes(); // Recursively set the real window sizes
f03fc89f 1145 }
5d4b632b 1146
f03fc89f
VZ
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.
1154bool 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
1165bool 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
1176bool 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();
34636400 1191 if ( !child->IsTopLevel() )
f03fc89f
VZ
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
1217void 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 }
f1df0927 1231
f03fc89f
VZ
1232 wxWindowList::Node *node = GetChildren().GetFirst();
1233 while (node)
1234 {
1235 wxWindow *win = node->GetData();
34636400 1236 if ( !win->IsTopLevel() )
f03fc89f
VZ
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.
1244void wxWindowBase::SetConstraintSizes(bool recurse)
1245{
1246 wxLayoutConstraints *constr = GetConstraints();
4b7f2165 1247 if ( constr && constr->AreSatisfied() )
f03fc89f
VZ
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
f03fc89f 1254 if ( (constr->width.GetRelationship() != wxAsIs ) ||
3417c2cd 1255 (constr->height.GetRelationship() != wxAsIs) )
f03fc89f 1256 {
3417c2cd 1257 SetSize(x, y, w, h);
f03fc89f
VZ
1258 }
1259 else
1260 {
3417c2cd
RR
1261 // If we don't want to resize this window, just move it...
1262 Move(x, y);
f03fc89f
VZ
1263 }
1264 }
1265 else if ( constr )
1266 {
4b7f2165 1267 wxLogDebug(wxT("Constraints not satisfied for %s named '%s'."),
f1df0927 1268 GetClassInfo()->GetClassName(),
4b7f2165 1269 GetName().c_str());
f03fc89f
VZ
1270 }
1271
1272 if ( recurse )
1273 {
1274 wxWindowList::Node *node = GetChildren().GetFirst();
1275 while (node)
1276 {
1277 wxWindow *win = node->GetData();
e2f9212c 1278 if ( !win->IsTopLevel() && win->GetConstraints() )
f03fc89f
VZ
1279 win->SetConstraintSizes();
1280 node = node->GetNext();
1281 }
1282 }
1283}
1284
f03fc89f
VZ
1285// Only set the size/position of the constraint (if any)
1286void 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
1314void 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
1332void 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
1344void 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
a200c35e
VS
1356void 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
f03fc89f
VZ
1373void 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// ----------------------------------------------------------------------------
7ec1983b
VZ
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.
f03fc89f 1395void wxWindowBase::UpdateWindowUI()
7ec1983b 1396{
1e6feb95 1397#if wxUSE_CONTROLS
26bf1ce0
VZ
1398 wxUpdateUIEvent event(GetId());
1399 event.m_eventObject = this;
1400
1401 if ( GetEventHandler()->ProcessEvent(event) )
7ec1983b 1402 {
26bf1ce0
VZ
1403 if ( event.GetSetEnabled() )
1404 Enable(event.GetEnabled());
7ec1983b 1405
26bf1ce0 1406 if ( event.GetSetText() )
f03fc89f 1407 {
f7637829 1408 wxControl *control = wxDynamicCastThis(wxControl);
26bf1ce0 1409 if ( control )
34636400 1410 {
1e6feb95 1411#if wxUSE_TEXTCTRL
26bf1ce0
VZ
1412 wxTextCtrl *text = wxDynamicCast(control, wxTextCtrl);
1413 if ( text )
1414 text->SetValue(event.GetText());
1415 else
1e6feb95 1416#endif // wxUSE_TEXTCTRL
34636400
VZ
1417 control->SetLabel(event.GetText());
1418 }
26bf1ce0 1419 }
f03fc89f 1420
88ac883a 1421#if wxUSE_CHECKBOX
f7637829 1422 wxCheckBox *checkbox = wxDynamicCastThis(wxCheckBox);
26bf1ce0
VZ
1423 if ( checkbox )
1424 {
1425 if ( event.GetSetChecked() )
1426 checkbox->SetValue(event.GetChecked());
1427 }
88ac883a
VZ
1428#endif // wxUSE_CHECKBOX
1429
b3402d0d 1430#if wxUSE_RADIOBTN
f7637829 1431 wxRadioButton *radiobtn = wxDynamicCastThis(wxRadioButton);
26bf1ce0
VZ
1432 if ( radiobtn )
1433 {
1434 if ( event.GetSetChecked() )
1435 radiobtn->SetValue(event.GetChecked());
f03fc89f 1436 }
b3402d0d 1437#endif // wxUSE_RADIOBTN
7ec1983b 1438 }
1e6feb95 1439#endif // wxUSE_CONTROLS
7ec1983b 1440}
fd71308f 1441
f03fc89f
VZ
1442// ----------------------------------------------------------------------------
1443// dialog units translations
1444// ----------------------------------------------------------------------------
1445
1446wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt)
fd71308f
JS
1447{
1448 int charWidth = GetCharWidth();
1449 int charHeight = GetCharHeight();
5d9c2818
RD
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) ;
fd71308f
JS
1455
1456 return pt2;
1457}
1458
f03fc89f 1459wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt)
fd71308f
JS
1460{
1461 int charWidth = GetCharWidth();
1462 int charHeight = GetCharHeight();
5d9c2818
RD
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) ;
fd71308f
JS
1468
1469 return pt2;
1470}
1471
f03fc89f
VZ
1472// ----------------------------------------------------------------------------
1473// event handlers
1474// ----------------------------------------------------------------------------
1475
1476// propagate the colour change event to the subwindows
1477void 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
1496void wxWindowBase::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
1497{
1498 TransferDataToWindow();
1499}
1500
a02dc3e3
VZ
1501// process Ctrl-Alt-mclick
1502void wxWindowBase::OnMiddleClick( wxMouseEvent& event )
1503{
1e6feb95 1504#if wxUSE_MSGDLG
a02dc3e3
VZ
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;
ff8fda36
GD
1512 case wxMAC:
1513 case wxMAC_DARWIN: port = _T("Mac"); break;
a02dc3e3
VZ
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(
1bc3fa01 1536 " wxWindows Library (%s port)\nVersion %u.%u.%u, compiled at %s %s\n Copyright (c) 1995-2001 wxWindows team"
a02dc3e3
VZ
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
1e6feb95 1550#endif // wxUSE_MSGDLG
a02dc3e3
VZ
1551 {
1552 event.Skip();
1553 }
1554}
1555
f03fc89f
VZ
1556// ----------------------------------------------------------------------------
1557// list classes implementation
1558// ----------------------------------------------------------------------------
1559
1560void wxWindowListNode::DeleteData()
1561{
1562 delete (wxWindow *)GetData();
1563}
1564
1e6feb95
VZ
1565// ----------------------------------------------------------------------------
1566// borders
1567// ----------------------------------------------------------------------------
1568
1569wxBorder 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
1580wxBorder wxWindowBase::GetDefaultBorder() const
1581{
1582 return wxBORDER_NONE;
1583}
1584
1585// ----------------------------------------------------------------------------
1586// hit testing
1587// ----------------------------------------------------------------------------
1588
1589wxHitTest 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