]> git.saurik.com Git - wxWidgets.git/blob - src/qt/window.cpp
More configure fixes
[wxWidgets.git] / src / qt / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: window.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Created: 01/02/97
6 // Id:
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11
12 #ifdef __GNUG__
13 #pragma implementation "window.h"
14 #endif
15
16 #include "wx/defs.h"
17 #include "wx/window.h"
18 #include "wx/dc.h"
19 #include "wx/frame.h"
20 #include "wx/app.h"
21 #include "wx/layout.h"
22 #include "wx/utils.h"
23 #include "wx/dialog.h"
24 #include "wx/msgdlg.h"
25 #include "wx/dcclient.h"
26 #include "wx/dnd.h"
27 #include "wx/mdi.h"
28 #include "wx/notebook.h"
29 #include "wx/statusbr.h"
30 #include <math.h>
31
32 //-----------------------------------------------------------------------------
33 // data
34 //-----------------------------------------------------------------------------
35
36 extern wxList wxPendingDelete;
37 extern wxList wxTopLevelWindows;
38
39 //-----------------------------------------------------------------------------
40 // wxWindow implementation
41 //-----------------------------------------------------------------------------
42
43 IMPLEMENT_DYNAMIC_CLASS(wxWindow,wxEvtHandler)
44
45 BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
46 EVT_SIZE(wxWindow::OnSize)
47 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
48 EVT_INIT_DIALOG(wxWindow::OnInitDialog)
49 EVT_IDLE(wxWindow::OnIdle)
50 END_EVENT_TABLE()
51
52 wxWindow::wxWindow()
53 {
54 m_parent = NULL;
55 m_children.DeleteContents( FALSE );
56 m_x = 0;
57 m_y = 0;
58 m_width = 0;
59 m_height = 0;
60 m_retCode = 0;
61 m_eventHandler = this;
62 m_windowValidator = NULL;
63 m_windowId = -1;
64 m_cursor = new wxCursor( wxCURSOR_ARROW );
65 m_font = *wxSWISS_FONT;
66 m_windowStyle = 0;
67 m_windowName = "noname";
68 m_constraints = NULL;
69 m_constraintsInvolvedIn = NULL;
70 m_windowSizer = NULL;
71 m_sizerParent = NULL;
72 m_autoLayout = FALSE;
73 m_pDropTarget = NULL;
74 };
75
76 wxWindow::wxWindow( wxWindow *parent, wxWindowID id,
77 const wxPoint &pos, const wxSize &size,
78 long style, const wxString &name )
79 {
80 Create( parent, id, pos, size, style, name );
81 };
82
83 bool wxWindow::Create( wxWindow *parent, wxWindowID id,
84 const wxPoint &pos, const wxSize &size,
85 long style, const wxString &name )
86 {
87 return TRUE;
88 };
89
90 wxWindow::~wxWindow(void)
91 {
92 DestroyChildren();
93
94 // delete m_cursor;
95
96 DeleteRelatedConstraints();
97 if (m_constraints)
98 {
99 // This removes any dangling pointers to this window
100 // in other windows' constraintsInvolvedIn lists.
101 UnsetConstraints(m_constraints);
102 delete m_constraints;
103 m_constraints = NULL;
104 }
105 if (m_windowSizer)
106 {
107 delete m_windowSizer;
108 m_windowSizer = NULL;
109 }
110 // If this is a child of a sizer, remove self from parent
111 if (m_sizerParent)
112 m_sizerParent->RemoveChild((wxWindow *)this);
113
114 // Just in case the window has been Closed, but
115 // we're then deleting immediately: don't leave
116 // dangling pointers.
117 wxPendingDelete.DeleteObject(this);
118
119 // Just in case we've loaded a top-level window via
120 // wxWindow::LoadNativeDialog but we weren't a dialog
121 // class
122 wxTopLevelWindows.DeleteObject(this);
123
124 };
125
126 bool wxWindow::Close( bool force )
127 {
128 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
129 event.SetEventObject(this);
130 event.SetForce(force);
131
132 return GetEventHandler()->ProcessEvent(event);
133 };
134
135 bool wxWindow::Destroy(void)
136 {
137 m_hasVMT = FALSE;
138 delete this;
139 return TRUE;
140 };
141
142 bool wxWindow::DestroyChildren(void)
143 {
144 if (GetChildren())
145 {
146 wxNode *node;
147 while ((node = GetChildren()->First()) != (wxNode *)NULL)
148 {
149 wxWindow *child;
150 if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL)
151 {
152 delete child;
153 if (GetChildren()->Member(child)) delete node;
154 };
155 };
156 };
157 return TRUE;
158 };
159
160 void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) )
161 {
162 // are we to set fonts here ?
163 };
164
165 void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags )
166 {
167
168 int newX = x;
169 int newY = y;
170 int newW = width;
171 int newH = height;
172
173 if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
174 {
175 if (newX == -1) newX = m_x;
176 if (newY == -1) newY = m_y;
177 if (newW == -1) newW = m_width;
178 if (newH == -1) newH = m_height;
179 };
180
181 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
182 {
183 if (newW == -1) newW = 80;
184 };
185
186 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
187 {
188 if (newH == -1) newH = 26;
189 };
190
191 if ((m_x != newX) || (m_y != newY) || (!m_sizeSet))
192 {
193 m_x = newX;
194 m_y = newY;
195 //
196 };
197 if ((m_width != newW) || (m_height != newH) || (!m_sizeSet))
198 {
199 m_width = newW;
200 m_height = newH;
201 //
202 };
203
204 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
205 event.SetEventObject( this );
206 ProcessEvent( event );
207 };
208
209 void wxWindow::SetSize( int width, int height )
210 {
211 SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING );
212 };
213
214 void wxWindow::Move( int x, int y )
215 {
216 SetSize( x, y, -1, -1, wxSIZE_USE_EXISTING );
217 };
218
219 void wxWindow::GetSize( int *width, int *height ) const
220 {
221 if (width) (*width) = m_width;
222 if (height) (*height) = m_height;
223 };
224
225 void wxWindow::SetClientSize( int width, int height )
226 {
227 };
228
229 void wxWindow::GetClientSize( int *width, int *height ) const
230 {
231 };
232
233 void wxWindow::GetPosition( int *x, int *y ) const
234 {
235 if (x) (*x) = m_x;
236 if (y) (*y) = m_y;
237 };
238
239 void wxWindow::ClientToScreen( int *x, int *y )
240 {
241 };
242
243 void wxWindow::ScreenToClient( int *x, int *y )
244 {
245 };
246
247 void wxWindow::Centre( int direction )
248 {
249 };
250
251 void wxWindow::Fit(void)
252 {
253 int maxX = 0;
254 int maxY = 0;
255 wxNode *node = GetChildren()->First();
256 while ( node )
257 {
258 wxWindow *win = (wxWindow *)node->Data();
259 int wx, wy, ww, wh;
260 win->GetPosition(&wx, &wy);
261 win->GetSize(&ww, &wh);
262 if ( wx + ww > maxX )
263 maxX = wx + ww;
264 if ( wy + wh > maxY )
265 maxY = wy + wh;
266
267 node = node->Next();
268 }
269 SetClientSize(maxX + 5, maxY + 10);
270 };
271
272 void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
273 {
274 //if (GetAutoLayout()) Layout();
275 };
276
277 bool wxWindow::Show( bool show )
278 {
279 return TRUE;
280 };
281
282 void wxWindow::Enable( bool enable )
283 {
284 m_isEnabled = enable;
285 };
286
287 void wxWindow::MakeModal( bool modal )
288 {
289 }
290
291 void wxWindow::SetFocus(void)
292 {
293 };
294
295 bool wxWindow::OnClose(void)
296 {
297 return TRUE;
298 };
299
300 void wxWindow::AddChild( wxWindow *child )
301 {
302 };
303
304 wxList *wxWindow::GetChildren(void)
305 {
306 return (&m_children);
307 };
308
309 void wxWindow::RemoveChild( wxWindow *child )
310 {
311 if (GetChildren())
312 GetChildren()->DeleteObject( child );
313 child->m_parent = NULL;
314 };
315
316 void wxWindow::SetReturnCode( int retCode )
317 {
318 m_retCode = retCode;
319 };
320
321 int wxWindow::GetReturnCode(void)
322 {
323 return m_retCode;
324 };
325
326 wxWindow *wxWindow::GetParent(void)
327 {
328 return m_parent;
329 };
330
331 wxEvtHandler *wxWindow::GetEventHandler(void)
332 {
333 return m_eventHandler;
334 };
335
336 void wxWindow::SetEventhandler( wxEvtHandler *handler )
337 {
338 m_eventHandler = handler;
339 };
340
341 wxValidator *wxWindow::GetValidator(void)
342 {
343 return m_windowValidator;
344 };
345
346 void wxWindow::SetValidator( wxValidator *validator )
347 {
348 m_windowValidator = validator;
349 };
350
351 bool wxWindow::IsBeingDeleted(void)
352 {
353 return FALSE;
354 };
355
356 void wxWindow::SetId( wxWindowID id )
357 {
358 m_windowId = id;
359 };
360
361 wxWindowID wxWindow::GetId(void)
362 {
363 return m_windowId;
364 };
365
366 void wxWindow::SetCursor( const wxCursor &cursor )
367 {
368 if (*m_cursor == cursor) return;
369 (*m_cursor) = cursor;
370 };
371
372 void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
373 {
374 };
375
376 bool wxWindow::IsExposed( long x, long y )
377 {
378 return (m_updateRegion.Contains( x, y ) != wxOutRegion );
379 };
380
381 bool wxWindow::IsExposed( long x, long y, long width, long height )
382 {
383 return (m_updateRegion.Contains( x, y, width, height ) != wxOutRegion );
384 };
385
386 void wxWindow::Clear(void)
387 {
388 };
389
390 wxColour wxWindow::GetBackgroundColour(void) const
391 {
392 return m_backgroundColour;
393 };
394
395 void wxWindow::SetBackgroundColour( const wxColour &colour )
396 {
397 m_backgroundColour = colour;
398 };
399
400 bool wxWindow::Validate(void)
401 {
402 wxNode *node = GetChildren()->First();
403 while (node)
404 {
405 wxWindow *child = (wxWindow *)node->Data();
406 if (child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this))
407 { return FALSE; }
408 node = node->Next();
409 };
410 return TRUE;
411 };
412
413 bool wxWindow::TransferDataToWindow(void)
414 {
415 wxNode *node = GetChildren()->First();
416 while (node)
417 {
418 wxWindow *child = (wxWindow *)node->Data();
419 if (child->GetValidator() && /* child->GetValidator()->Ok() && */
420 !child->GetValidator()->TransferToWindow() )
421 {
422 wxMessageBox( "Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION );
423 return FALSE;
424 };
425 node = node->Next();
426 };
427 return TRUE;
428 };
429
430 bool wxWindow::TransferDataFromWindow(void)
431 {
432 wxNode *node = GetChildren()->First();
433 while (node)
434 {
435 wxWindow *child = (wxWindow *)node->Data();
436 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferFromWindow() )
437 { return FALSE; }
438 node = node->Next();
439 }
440 return TRUE;
441 };
442
443 void wxWindow::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
444 {
445 TransferDataToWindow();
446 };
447
448 void wxWindow::InitDialog(void)
449 {
450 wxInitDialogEvent event(GetId());
451 event.SetEventObject( this );
452 GetEventHandler()->ProcessEvent(event);
453 };
454
455 void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
456 {
457 if (m_pDropTarget)
458 {
459 m_pDropTarget->UnregisterWidget( dnd_widget );
460 delete m_pDropTarget;
461 };
462 m_pDropTarget = dropTarget;
463 if (m_pDropTarget)
464 {
465 };
466 };
467
468 wxDropTarget *wxWindow::GetDropTarget() const
469 {
470 return m_pDropTarget;
471 };
472
473 void wxWindow::SetFont( const wxFont &font )
474 {
475 m_font = font;
476 /*
477 ...
478 */
479 };
480
481 wxFont *wxWindow::GetFont(void)
482 {
483 return &m_font;
484 };
485
486 void wxWindow::SetWindowStyleFlag( long flag )
487 {
488 m_windowStyle = flag;
489 };
490
491 long wxWindow::GetWindowStyleFlag(void) const
492 {
493 return m_windowStyle;
494 };
495
496 void wxWindow::CaptureMouse(void)
497 {
498 };
499
500 void wxWindow::ReleaseMouse(void)
501 {
502 };
503
504 void wxWindow::SetTitle( const wxString &WXUNUSED(title) )
505 {
506 };
507
508 wxString wxWindow::GetTitle(void) const
509 {
510 return (wxString&)m_windowName;
511 };
512
513 wxString wxWindow::GetLabel(void) const
514 {
515 return GetTitle();
516 };
517
518 void wxWindow::SetName( const wxString &name )
519 {
520 m_windowName = name;
521 };
522
523 wxString wxWindow::GetName(void) const
524 {
525 return (wxString&)m_windowName;
526 };
527
528 bool wxWindow::IsShown(void) const
529 {
530 return m_isShown;
531 };
532
533 bool wxWindow::IsRetained(void)
534 {
535 return FALSE;
536 };
537
538 wxWindow *wxWindow::FindWindow( long id )
539 {
540 if (id == m_windowId) return this;
541 wxNode *node = m_children.First();
542 while (node)
543 {
544 wxWindow *child = (wxWindow*)node->Data();
545 wxWindow *res = child->FindWindow( id );
546 if (res) return res;
547 node = node->Next();
548 };
549 return NULL;
550 };
551
552 wxWindow *wxWindow::FindWindow( const wxString& name )
553 {
554 if (name == m_windowName) return this;
555 wxNode *node = m_children.First();
556 while (node)
557 {
558 wxWindow *child = (wxWindow*)node->Data();
559 wxWindow *res = child->FindWindow( name );
560 if (res) return res;
561 node = node->Next();
562 };
563 return NULL;
564 };
565
566 void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
567 int range, bool WXUNUSED(refresh) )
568 {
569 };
570
571 void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
572 {
573 };
574
575 int wxWindow::GetScrollThumb( int orient ) const
576 {
577 };
578
579 int wxWindow::GetScrollPos( int orient ) const
580 {
581 };
582
583 int wxWindow::GetScrollRange( int orient ) const
584 {
585 };
586
587 void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
588 {
589 };
590
591 //-------------------------------------------------------------------------------------
592 // Layout
593 //-------------------------------------------------------------------------------------
594
595 wxLayoutConstraints *wxWindow::GetConstraints(void) const
596 {
597 return m_constraints;
598 };
599
600 void wxWindow::SetConstraints( wxLayoutConstraints *constraints )
601 {
602 if (m_constraints)
603 {
604 UnsetConstraints(m_constraints);
605 delete m_constraints;
606 }
607 m_constraints = constraints;
608 if (m_constraints)
609 {
610 // Make sure other windows know they're part of a 'meaningful relationship'
611 if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
612 m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
613 if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
614 m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
615 if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
616 m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
617 if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
618 m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
619 if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
620 m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
621 if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
622 m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
623 if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
624 m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
625 if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
626 m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
627 }
628 ;
629 }
630 ;
631
632 void wxWindow::SetAutoLayout( bool autoLayout )
633 {
634 m_autoLayout = autoLayout;
635 };
636
637 bool wxWindow::GetAutoLayout(void) const
638 {
639 return m_autoLayout;
640 };
641
642 wxSizer *wxWindow::GetSizer(void) const
643 {
644 return m_windowSizer;
645 };
646
647 void wxWindow::SetSizerParent( wxWindow *win )
648 {
649 m_sizerParent = win;
650 };
651
652 wxWindow *wxWindow::GetSizerParent(void) const
653 {
654 return m_sizerParent;
655 };
656
657 // This removes any dangling pointers to this window
658 // in other windows' constraintsInvolvedIn lists.
659 void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
660 {
661 if (c)
662 {
663 if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
664 c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
665 if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
666 c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
667 if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
668 c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
669 if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
670 c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
671 if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
672 c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
673 if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
674 c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
675 if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
676 c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
677 if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
678 c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
679 }
680 }
681
682 // Back-pointer to other windows we're involved with, so if we delete
683 // this window, we must delete any constraints we're involved with.
684 void wxWindow::AddConstraintReference(wxWindow *otherWin)
685 {
686 if (!m_constraintsInvolvedIn)
687 m_constraintsInvolvedIn = new wxList;
688 if (!m_constraintsInvolvedIn->Member(otherWin))
689 m_constraintsInvolvedIn->Append(otherWin);
690 }
691
692 // REMOVE back-pointer to other windows we're involved with.
693 void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
694 {
695 if (m_constraintsInvolvedIn)
696 m_constraintsInvolvedIn->DeleteObject(otherWin);
697 }
698
699 // Reset any constraints that mention this window
700 void wxWindow::DeleteRelatedConstraints(void)
701 {
702 if (m_constraintsInvolvedIn)
703 {
704 wxNode *node = m_constraintsInvolvedIn->First();
705 while (node)
706 {
707 wxWindow *win = (wxWindow *)node->Data();
708 wxNode *next = node->Next();
709 wxLayoutConstraints *constr = win->GetConstraints();
710
711 // Reset any constraints involving this window
712 if (constr)
713 {
714 constr->left.ResetIfWin((wxWindow *)this);
715 constr->top.ResetIfWin((wxWindow *)this);
716 constr->right.ResetIfWin((wxWindow *)this);
717 constr->bottom.ResetIfWin((wxWindow *)this);
718 constr->width.ResetIfWin((wxWindow *)this);
719 constr->height.ResetIfWin((wxWindow *)this);
720 constr->centreX.ResetIfWin((wxWindow *)this);
721 constr->centreY.ResetIfWin((wxWindow *)this);
722 }
723 delete node;
724 node = next;
725 }
726 delete m_constraintsInvolvedIn;
727 m_constraintsInvolvedIn = NULL;
728 }
729 }
730
731 void wxWindow::SetSizer(wxSizer *sizer)
732 {
733 m_windowSizer = sizer;
734 if (sizer)
735 sizer->SetSizerParent((wxWindow *)this);
736 }
737
738 /*
739 * New version
740 */
741
742 bool wxWindow::Layout(void)
743 {
744 if (GetConstraints())
745 {
746 int w, h;
747 GetClientSize(&w, &h);
748 GetConstraints()->width.SetValue(w);
749 GetConstraints()->height.SetValue(h);
750 }
751
752 // If top level (one sizer), evaluate the sizer's constraints.
753 if (GetSizer())
754 {
755 int noChanges;
756 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
757 GetSizer()->LayoutPhase1(&noChanges);
758 GetSizer()->LayoutPhase2(&noChanges);
759 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
760 return TRUE;
761 }
762 else
763 {
764 // Otherwise, evaluate child constraints
765 ResetConstraints(); // Mark all constraints as unevaluated
766 DoPhase(1); // Just one phase need if no sizers involved
767 DoPhase(2);
768 SetConstraintSizes(); // Recursively set the real window sizes
769 }
770 return TRUE;
771 }
772
773
774 // Do a phase of evaluating constraints:
775 // the default behaviour. wxSizers may do a similar
776 // thing, but also impose their own 'constraints'
777 // and order the evaluation differently.
778 bool wxWindow::LayoutPhase1(int *noChanges)
779 {
780 wxLayoutConstraints *constr = GetConstraints();
781 if (constr)
782 {
783 return constr->SatisfyConstraints((wxWindow *)this, noChanges);
784 }
785 else
786 return TRUE;
787 }
788
789 bool wxWindow::LayoutPhase2(int *noChanges)
790 {
791 *noChanges = 0;
792
793 // Layout children
794 DoPhase(1);
795 DoPhase(2);
796 return TRUE;
797 }
798
799 // Do a phase of evaluating child constraints
800 bool wxWindow::DoPhase(int phase)
801 {
802 int noIterations = 0;
803 int maxIterations = 500;
804 int noChanges = 1;
805 int noFailures = 0;
806 wxList succeeded;
807 while ((noChanges > 0) && (noIterations < maxIterations))
808 {
809 noChanges = 0;
810 noFailures = 0;
811 wxNode *node = GetChildren()->First();
812 while (node)
813 {
814 wxWindow *child = (wxWindow *)node->Data();
815 if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
816 {
817 wxLayoutConstraints *constr = child->GetConstraints();
818 if (constr)
819 {
820 if (succeeded.Member(child))
821 {
822 }
823 else
824 {
825 int tempNoChanges = 0;
826 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
827 noChanges += tempNoChanges;
828 if (success)
829 {
830 succeeded.Append(child);
831 }
832 }
833 }
834 }
835 node = node->Next();
836 }
837 noIterations ++;
838 }
839 return TRUE;
840 }
841
842 void wxWindow::ResetConstraints(void)
843 {
844 wxLayoutConstraints *constr = GetConstraints();
845 if (constr)
846 {
847 constr->left.SetDone(FALSE);
848 constr->top.SetDone(FALSE);
849 constr->right.SetDone(FALSE);
850 constr->bottom.SetDone(FALSE);
851 constr->width.SetDone(FALSE);
852 constr->height.SetDone(FALSE);
853 constr->centreX.SetDone(FALSE);
854 constr->centreY.SetDone(FALSE);
855 }
856 wxNode *node = GetChildren()->First();
857 while (node)
858 {
859 wxWindow *win = (wxWindow *)node->Data();
860 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
861 win->ResetConstraints();
862 node = node->Next();
863 }
864 }
865
866 // Need to distinguish between setting the 'fake' size for
867 // windows and sizers, and setting the real values.
868 void wxWindow::SetConstraintSizes(bool recurse)
869 {
870 wxLayoutConstraints *constr = GetConstraints();
871 if (constr && constr->left.GetDone() && constr->right.GetDone() &&
872 constr->width.GetDone() && constr->height.GetDone())
873 {
874 int x = constr->left.GetValue();
875 int y = constr->top.GetValue();
876 int w = constr->width.GetValue();
877 int h = constr->height.GetValue();
878
879 // If we don't want to resize this window, just move it...
880 if ((constr->width.GetRelationship() != wxAsIs) ||
881 (constr->height.GetRelationship() != wxAsIs))
882 {
883 // Calls Layout() recursively. AAAGH. How can we stop that.
884 // Simply take Layout() out of non-top level OnSizes.
885 SizerSetSize(x, y, w, h);
886 }
887 else
888 {
889 SizerMove(x, y);
890 }
891 }
892 else if (constr)
893 {
894 char *windowClass = this->GetClassInfo()->GetClassName();
895
896 wxString winName;
897 if (GetName() == "")
898 winName = "unnamed";
899 else
900 winName = GetName();
901 wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName);
902 if (!constr->left.GetDone())
903 wxDebugMsg(" unsatisfied 'left' constraint.\n");
904 if (!constr->right.GetDone())
905 wxDebugMsg(" unsatisfied 'right' constraint.\n");
906 if (!constr->width.GetDone())
907 wxDebugMsg(" unsatisfied 'width' constraint.\n");
908 if (!constr->height.GetDone())
909 wxDebugMsg(" unsatisfied 'height' constraint.\n");
910 wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
911 }
912
913 if (recurse)
914 {
915 wxNode *node = GetChildren()->First();
916 while (node)
917 {
918 wxWindow *win = (wxWindow *)node->Data();
919 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
920 win->SetConstraintSizes();
921 node = node->Next();
922 }
923 }
924 }
925
926 // This assumes that all sizers are 'on' the same
927 // window, i.e. the parent of this window.
928 void wxWindow::TransformSizerToActual(int *x, int *y) const
929 {
930 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
931 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
932 return;
933
934 int xp, yp;
935 m_sizerParent->GetPosition(&xp, &yp);
936 m_sizerParent->TransformSizerToActual(&xp, &yp);
937 *x += xp;
938 *y += yp;
939 }
940
941 void wxWindow::SizerSetSize(int x, int y, int w, int h)
942 {
943 int xx = x;
944 int yy = y;
945 TransformSizerToActual(&xx, &yy);
946 SetSize(xx, yy, w, h);
947 }
948
949 void wxWindow::SizerMove(int x, int y)
950 {
951 int xx = x;
952 int yy = y;
953 TransformSizerToActual(&xx, &yy);
954 Move(xx, yy);
955 }
956
957 // Only set the size/position of the constraint (if any)
958 void wxWindow::SetSizeConstraint(int x, int y, int w, int h)
959 {
960 wxLayoutConstraints *constr = GetConstraints();
961 if (constr)
962 {
963 if (x != -1)
964 {
965 constr->left.SetValue(x);
966 constr->left.SetDone(TRUE);
967 }
968 if (y != -1)
969 {
970 constr->top.SetValue(y);
971 constr->top.SetDone(TRUE);
972 }
973 if (w != -1)
974 {
975 constr->width.SetValue(w);
976 constr->width.SetDone(TRUE);
977 }
978 if (h != -1)
979 {
980 constr->height.SetValue(h);
981 constr->height.SetDone(TRUE);
982 }
983 }
984 }
985
986 void wxWindow::MoveConstraint(int x, int y)
987 {
988 wxLayoutConstraints *constr = GetConstraints();
989 if (constr)
990 {
991 if (x != -1)
992 {
993 constr->left.SetValue(x);
994 constr->left.SetDone(TRUE);
995 }
996 if (y != -1)
997 {
998 constr->top.SetValue(y);
999 constr->top.SetDone(TRUE);
1000 }
1001 }
1002 }
1003
1004 void wxWindow::GetSizeConstraint(int *w, int *h) const
1005 {
1006 wxLayoutConstraints *constr = GetConstraints();
1007 if (constr)
1008 {
1009 *w = constr->width.GetValue();
1010 *h = constr->height.GetValue();
1011 }
1012 else
1013 GetSize(w, h);
1014 }
1015
1016 void wxWindow::GetClientSizeConstraint(int *w, int *h) const
1017 {
1018 wxLayoutConstraints *constr = GetConstraints();
1019 if (constr)
1020 {
1021 *w = constr->width.GetValue();
1022 *h = constr->height.GetValue();
1023 }
1024 else
1025 GetClientSize(w, h);
1026 }
1027
1028 void wxWindow::GetPositionConstraint(int *x, int *y) const
1029 {
1030 wxLayoutConstraints *constr = GetConstraints();
1031 if (constr)
1032 {
1033 *x = constr->left.GetValue();
1034 *y = constr->top.GetValue();
1035 }
1036 else
1037 GetPosition(x, y);
1038 }
1039
1040 bool wxWindow::AcceptsFocus() const
1041 {
1042 return IsEnabled() && IsShown();
1043 }
1044
1045 void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event) )
1046 {
1047 UpdateWindowUI();
1048 }