]> git.saurik.com Git - wxWidgets.git/blob - src/stubs/window.cpp
MSWProcessMessage speed up by a factor of 100 (at least)
[wxWidgets.git] / src / stubs / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: windows.cpp
3 // Purpose: wxWindow
4 // Author: AUTHOR
5 // Modified by:
6 // Created: ??/??/98
7 // RCS-ID: $Id$
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "window.h"
14 #endif
15
16 #include "wx/setup.h"
17 #include "wx/menu.h"
18 #include "wx/dc.h"
19 #include "wx/dcclient.h"
20 #include "wx/utils.h"
21 #include "wx/app.h"
22 #include "wx/panel.h"
23 #include "wx/layout.h"
24 #include "wx/dialog.h"
25 #include "wx/listbox.h"
26 #include "wx/button.h"
27 #include "wx/settings.h"
28 #include "wx/msgdlg.h"
29 #include "wx/frame.h"
30
31 #include "wx/menuitem.h"
32 #include "wx/log.h"
33
34 #if wxUSE_DRAG_AND_DROP
35 #include "wx/dnd.h"
36 #endif
37
38 #include <string.h>
39
40 extern wxList wxPendingDelete;
41
42 #if !USE_SHARED_LIBRARY
43 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxEvtHandler)
44
45 BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
46 EVT_CHAR(wxWindow::OnChar)
47 EVT_KEY_DOWN(wxWindow::OnKeyDown)
48 EVT_KEY_UP(wxWindow::OnKeyUp)
49 EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground)
50 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
51 EVT_INIT_DIALOG(wxWindow::OnInitDialog)
52 EVT_IDLE(wxWindow::OnIdle)
53 END_EVENT_TABLE()
54
55 #endif
56
57
58 // Constructor
59 wxWindow::wxWindow()
60 {
61 // Generic
62 m_isWindow = TRUE; // An optimization
63 m_windowId = 0;
64 m_windowStyle = 0;
65 m_windowParent = NULL;
66 m_windowEventHandler = this;
67 m_windowName = "";
68 m_windowCursor = *wxSTANDARD_CURSOR;
69 m_children = new wxList;
70 m_constraints = NULL;
71 m_constraintsInvolvedIn = NULL;
72 m_windowSizer = NULL;
73 m_sizerParent = NULL;
74 m_autoLayout = FALSE;
75 m_windowValidator = NULL;
76 m_defaultItem = NULL;
77 m_returnCode = 0;
78 m_caretWidth = 0; m_caretHeight = 0;
79 m_caretEnabled = FALSE;
80 m_caretShown = FALSE;
81 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE) ;
82 // m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW) ; ;
83 m_foregroundColour = *wxBLACK;
84
85 #if wxUSE_DRAG_AND_DROP
86 m_pDropTarget = NULL;
87 #endif
88 }
89
90 // Destructor
91 wxWindow::~wxWindow()
92 {
93 // Have to delete constraints/sizer FIRST otherwise
94 // sizers may try to look at deleted windows as they
95 // delete themselves.
96 #if wxUSE_CONSTRAINTS
97 DeleteRelatedConstraints();
98 if (m_constraints)
99 {
100 // This removes any dangling pointers to this window
101 // in other windows' constraintsInvolvedIn lists.
102 UnsetConstraints(m_constraints);
103 delete m_constraints;
104 m_constraints = NULL;
105 }
106 if (m_windowSizer)
107 {
108 delete m_windowSizer;
109 m_windowSizer = NULL;
110 }
111 // If this is a child of a sizer, remove self from parent
112 if (m_sizerParent)
113 m_sizerParent->RemoveChild((wxWindow *)this);
114 #endif
115
116 if (m_windowParent)
117 m_windowParent->RemoveChild(this);
118
119 DestroyChildren();
120
121 // TODO: destroy the window
122
123 delete m_children;
124 m_children = NULL;
125
126 // Just in case the window has been Closed, but
127 // we're then deleting immediately: don't leave
128 // dangling pointers.
129 wxPendingDelete.DeleteObject(this);
130
131 if ( m_windowValidator )
132 delete m_windowValidator;
133 }
134
135 // Destroy the window (delayed, if a managed window)
136 bool wxWindow::Destroy()
137 {
138 delete this;
139 return TRUE;
140 }
141
142 // Constructor
143 bool wxWindow::Create(wxWindow *parent, wxWindowID id,
144 const wxPoint& pos,
145 const wxSize& size,
146 long style,
147 const wxString& name)
148 {
149 // Generic
150 m_isWindow = TRUE; // An optimization
151 m_windowId = 0;
152 m_windowStyle = 0;
153 m_windowParent = NULL;
154 m_windowEventHandler = this;
155 m_windowName = "";
156 m_windowCursor = *wxSTANDARD_CURSOR;
157 m_constraints = NULL;
158 m_constraintsInvolvedIn = NULL;
159 m_windowSizer = NULL;
160 m_sizerParent = NULL;
161 m_autoLayout = FALSE;
162 m_windowValidator = NULL;
163
164 #if wxUSE_DRAG_AND_DROP
165 m_pDropTarget = NULL;
166 #endif
167
168 m_caretWidth = 0; m_caretHeight = 0;
169 m_caretEnabled = FALSE;
170 m_caretShown = FALSE;
171 m_minSizeX = -1;
172 m_minSizeY = -1;
173 m_maxSizeX = -1;
174 m_maxSizeY = -1;
175 m_defaultItem = NULL;
176 m_windowParent = NULL;
177 if (!parent)
178 return FALSE;
179
180 if (parent) parent->AddChild(this);
181
182 m_returnCode = 0;
183
184 SetName(name);
185
186 if ( id == -1 )
187 m_windowId = (int)NewControlId();
188 else
189 m_windowId = id;
190
191 // m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW) ; ;
192 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE) ;
193 m_foregroundColour = *wxBLACK;
194
195 m_windowStyle = style;
196
197 if ( id == -1 )
198 m_windowId = (int)NewControlId();
199 else
200 m_windowId = id;
201
202 // TODO: create the window
203
204 return TRUE;
205 }
206
207 void wxWindow::SetFocus()
208 {
209 // TODO
210 }
211
212 void wxWindow::Enable(bool enable)
213 {
214 // TODO
215 }
216
217 void wxWindow::CaptureMouse()
218 {
219 // TODO
220 }
221
222 void wxWindow::ReleaseMouse()
223 {
224 // TODO
225 }
226
227 // Push/pop event handler (i.e. allow a chain of event handlers
228 // be searched)
229 void wxWindow::PushEventHandler(wxEvtHandler *handler)
230 {
231 handler->SetNextHandler(GetEventHandler());
232 SetEventHandler(handler);
233 }
234
235 wxEvtHandler *wxWindow::PopEventHandler(bool deleteHandler)
236 {
237 if ( GetEventHandler() )
238 {
239 wxEvtHandler *handlerA = GetEventHandler();
240 wxEvtHandler *handlerB = handlerA->GetNextHandler();
241 handlerA->SetNextHandler(NULL);
242 SetEventHandler(handlerB);
243 if ( deleteHandler )
244 {
245 delete handlerA;
246 return NULL;
247 }
248 else
249 return handlerA;
250 }
251 else
252 return NULL;
253 }
254
255 #if wxUSE_DRAG_AND_DROP
256
257 void wxWindow::SetDropTarget(wxDropTarget *pDropTarget)
258 {
259 if ( m_pDropTarget != 0 ) {
260 delete m_pDropTarget;
261 }
262
263 m_pDropTarget = pDropTarget;
264 if ( m_pDropTarget != 0 )
265 {
266 // TODO
267 }
268 }
269
270 #endif
271
272 // Old style file-manager drag&drop
273 void wxWindow::DragAcceptFiles(bool accept)
274 {
275 // TODO
276 }
277
278 // Get total size
279 void wxWindow::GetSize(int *x, int *y) const
280 {
281 // TODO
282 }
283
284 void wxWindow::GetPosition(int *x, int *y) const
285 {
286 // TODO
287 }
288
289 void wxWindow::ScreenToClient(int *x, int *y) const
290 {
291 // TODO
292 }
293
294 void wxWindow::ClientToScreen(int *x, int *y) const
295 {
296 // TODO
297 }
298
299 void wxWindow::SetCursor(const wxCursor& cursor)
300 {
301 m_windowCursor = cursor;
302 if (m_windowCursor.Ok())
303 {
304 // TODO
305 }
306 }
307
308
309 // Get size *available for subwindows* i.e. excluding menu bar etc.
310 void wxWindow::GetClientSize(int *x, int *y) const
311 {
312 // TODO
313 }
314
315 void wxWindow::SetSize(int x, int y, int width, int height, int sizeFlags)
316 {
317 // TODO
318 }
319
320 void wxWindow::SetClientSize(int width, int height)
321 {
322 // TODO
323 }
324
325 // For implementation purposes - sometimes decorations make the client area
326 // smaller
327 wxPoint wxWindow::GetClientAreaOrigin() const
328 {
329 return wxPoint(0, 0);
330 }
331
332 // Makes an adjustment to the window position (for example, a frame that has
333 // a toolbar that it manages itself).
334 void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
335 {
336 if (((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent())
337 {
338 wxPoint pt(GetParent()->GetClientAreaOrigin());
339 x += pt.x; y += pt.y;
340 }
341 }
342
343 bool wxWindow::Show(bool show)
344 {
345 // TODO
346 return FALSE;
347 }
348
349 bool wxWindow::IsShown() const
350 {
351 // TODO
352 return FALSE;
353 }
354
355 int wxWindow::GetCharHeight() const
356 {
357 // TODO
358 return 0;
359 }
360
361 int wxWindow::GetCharWidth() const
362 {
363 // TODO
364 return 0;
365 }
366
367 void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
368 int *descent, int *externalLeading, const wxFont *theFont, bool) const
369 {
370 wxFont *fontToUse = (wxFont *)theFont;
371 if (!fontToUse)
372 fontToUse = (wxFont *) & m_windowFont;
373
374 // TODO
375 }
376
377 void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
378 {
379 // TODO
380 }
381
382 // Responds to colour changes: passes event on to children.
383 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event)
384 {
385 wxNode *node = GetChildren().First();
386 while ( node )
387 {
388 // Only propagate to non-top-level windows
389 wxWindow *win = (wxWindow *)node->Data();
390 if ( win->GetParent() )
391 {
392 wxSysColourChangedEvent event2;
393 event.m_eventObject = win;
394 win->GetEventHandler()->ProcessEvent(event2);
395 }
396
397 node = node->Next();
398 }
399 }
400
401 // This can be called by the app (or wxWindows) to do default processing for the current
402 // event. Save message/event info in wxWindow so they can be used in this function.
403 long wxWindow::Default()
404 {
405 // TODO
406 return 0;
407 }
408
409 void wxWindow::InitDialog()
410 {
411 wxInitDialogEvent event(GetId());
412 event.SetEventObject( this );
413 GetEventHandler()->ProcessEvent(event);
414 }
415
416 // Default init dialog behaviour is to transfer data to window
417 void wxWindow::OnInitDialog(wxInitDialogEvent& event)
418 {
419 TransferDataToWindow();
420 }
421
422 // Caret manipulation
423 void wxWindow::CreateCaret(int w, int h)
424 {
425 m_caretWidth = w;
426 m_caretHeight = h;
427 m_caretEnabled = TRUE;
428 }
429
430 void wxWindow::CreateCaret(const wxBitmap *WXUNUSED(bitmap))
431 {
432 // TODO
433 }
434
435 void wxWindow::ShowCaret(bool show)
436 {
437 // TODO
438 }
439
440 void wxWindow::DestroyCaret()
441 {
442 // TODO
443 m_caretEnabled = FALSE;
444 }
445
446 void wxWindow::SetCaretPos(int x, int y)
447 {
448 // TODO
449 }
450
451 void wxWindow::GetCaretPos(int *x, int *y) const
452 {
453 // TODO
454 }
455
456 wxWindow *wxGetActiveWindow()
457 {
458 // TODO
459 return NULL;
460 }
461
462 void wxWindow::SetSizeHints(int minW, int minH, int maxW, int maxH, int WXUNUSED(incW), int WXUNUSED(incH))
463 {
464 m_minSizeX = minW;
465 m_minSizeY = minH;
466 m_maxSizeX = maxW;
467 m_maxSizeY = maxH;
468 }
469
470 void wxWindow::Centre(int direction)
471 {
472 int x, y, width, height, panel_width, panel_height, new_x, new_y;
473
474 wxWindow *father = (wxWindow *)GetParent();
475 if (!father)
476 return;
477
478 father->GetClientSize(&panel_width, &panel_height);
479 GetSize(&width, &height);
480 GetPosition(&x, &y);
481
482 new_x = -1;
483 new_y = -1;
484
485 if (direction & wxHORIZONTAL)
486 new_x = (int)((panel_width - width)/2);
487
488 if (direction & wxVERTICAL)
489 new_y = (int)((panel_height - height)/2);
490
491 SetSize(new_x, new_y, -1, -1);
492
493 }
494
495 // Coordinates relative to the window
496 void wxWindow::WarpPointer (int x_pos, int y_pos)
497 {
498 // TODO
499 }
500
501 void wxWindow::OnEraseBackground(wxEraseEvent& event)
502 {
503 // TODO
504 Default();
505 }
506
507 int wxWindow::GetScrollPos(int orient) const
508 {
509 // TODO
510 return 0;
511 }
512
513 // This now returns the whole range, not just the number
514 // of positions that we can scroll.
515 int wxWindow::GetScrollRange(int orient) const
516 {
517 // TODO
518 return 0;
519 }
520
521 int wxWindow::GetScrollThumb(int orient) const
522 {
523 // TODO
524 return 0;
525 }
526
527 void wxWindow::SetScrollPos(int orient, int pos, bool refresh)
528 {
529 // TODO
530 return;
531 }
532
533 // New function that will replace some of the above.
534 void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
535 int range, bool refresh)
536 {
537 // TODO
538 }
539
540 // Does a physical scroll
541 void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
542 {
543 // TODO
544 return;
545 }
546
547 void wxWindow::SetFont(const wxFont& font)
548 {
549 m_windowFont = font;
550
551 if (!m_windowFont.Ok())
552 return;
553 // TODO
554 }
555
556 void wxWindow::OnChar(wxKeyEvent& event)
557 {
558 /* ??
559 if ( event.KeyCode() == WXK_TAB ) {
560 // propagate the TABs to the parent - it's up to it to decide what
561 // to do with it
562 if ( GetParent() ) {
563 if ( GetParent()->ProcessEvent(event) )
564 return;
565 }
566 }
567 */
568 Default();
569 }
570
571 void wxWindow::OnKeyDown(wxKeyEvent& event)
572 {
573 Default();
574 }
575
576 void wxWindow::OnKeyUp(wxKeyEvent& event)
577 {
578 Default();
579 }
580
581 void wxWindow::OnPaint(wxPaintEvent& event)
582 {
583 Default();
584 }
585
586 bool wxWindow::IsEnabled() const
587 {
588 // TODO
589 return FALSE;
590 }
591
592 // Dialog support: override these and call
593 // base class members to add functionality
594 // that can't be done using validators.
595 // NOTE: these functions assume that controls
596 // are direct children of this window, not grandchildren
597 // or other levels of descendant.
598
599 // Transfer values to controls. If returns FALSE,
600 // it's an application error (pops up a dialog)
601 bool wxWindow::TransferDataToWindow()
602 {
603 wxNode *node = GetChildren().First();
604 while ( node )
605 {
606 wxWindow *child = (wxWindow *)node->Data();
607 if ( child->GetValidator() &&
608 !child->GetValidator()->TransferToWindow() )
609 {
610 wxMessageBox("Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION);
611 return FALSE;
612 }
613
614 node = node->Next();
615 }
616 return TRUE;
617 }
618
619 // Transfer values from controls. If returns FALSE,
620 // validation failed: don't quit
621 bool wxWindow::TransferDataFromWindow()
622 {
623 wxNode *node = GetChildren().First();
624 while ( node )
625 {
626 wxWindow *child = (wxWindow *)node->Data();
627 if ( child->GetValidator() && !child->GetValidator()->TransferFromWindow() )
628 {
629 return FALSE;
630 }
631
632 node = node->Next();
633 }
634 return TRUE;
635 }
636
637 bool wxWindow::Validate()
638 {
639 wxNode *node = GetChildren().First();
640 while ( node )
641 {
642 wxWindow *child = (wxWindow *)node->Data();
643 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this) )
644 {
645 return FALSE;
646 }
647
648 node = node->Next();
649 }
650 return TRUE;
651 }
652
653 // Get the window with the focus
654 wxWindow *wxWindow::FindFocus()
655 {
656 // TODO
657 return NULL;
658 }
659
660 void wxWindow::AddChild(wxWindow *child)
661 {
662 GetChildren().Append(child);
663 child->m_windowParent = this;
664 }
665
666 void wxWindow::RemoveChild(wxWindow *child)
667 {
668 GetChildren().DeleteObject(child);
669 child->m_windowParent = NULL;
670 }
671
672 void wxWindow::DestroyChildren()
673 {
674 wxNode *node;
675 while ((node = GetChildren().First()) != (wxNode *)NULL) {
676 wxWindow *child;
677 if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL) {
678 delete child;
679 if ( GetChildren().Member(child) )
680 delete node;
681 }
682 } /* while */
683 }
684
685 void wxWindow::MakeModal(bool modal)
686 {
687 // Disable all other windows
688 if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
689 {
690 wxNode *node = wxTopLevelWindows.First();
691 while (node)
692 {
693 wxWindow *win = (wxWindow *)node->Data();
694 if (win != this)
695 win->Enable(!modal);
696
697 node = node->Next();
698 }
699 }
700 }
701
702 // If nothing defined for this, try the parent.
703 // E.g. we may be a button loaded from a resource, with no callback function
704 // defined.
705 void wxWindow::OnCommand(wxWindow& win, wxCommandEvent& event)
706 {
707 if (GetEventHandler()->ProcessEvent(event) )
708 return;
709 if (m_windowParent)
710 m_windowParent->GetEventHandler()->OnCommand(win, event);
711 }
712
713 void wxWindow::SetConstraints(wxLayoutConstraints *c)
714 {
715 if (m_constraints)
716 {
717 UnsetConstraints(m_constraints);
718 delete m_constraints;
719 }
720 m_constraints = c;
721 if (m_constraints)
722 {
723 // Make sure other windows know they're part of a 'meaningful relationship'
724 if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
725 m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
726 if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
727 m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
728 if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
729 m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
730 if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
731 m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
732 if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
733 m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
734 if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
735 m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
736 if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
737 m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
738 if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
739 m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
740 }
741 }
742
743 // This removes any dangling pointers to this window
744 // in other windows' constraintsInvolvedIn lists.
745 void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
746 {
747 if (c)
748 {
749 if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
750 c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
751 if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
752 c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
753 if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
754 c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
755 if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
756 c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
757 if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
758 c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
759 if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
760 c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
761 if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
762 c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
763 if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
764 c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
765 }
766 }
767
768 // Back-pointer to other windows we're involved with, so if we delete
769 // this window, we must delete any constraints we're involved with.
770 void wxWindow::AddConstraintReference(wxWindow *otherWin)
771 {
772 if (!m_constraintsInvolvedIn)
773 m_constraintsInvolvedIn = new wxList;
774 if (!m_constraintsInvolvedIn->Member(otherWin))
775 m_constraintsInvolvedIn->Append(otherWin);
776 }
777
778 // REMOVE back-pointer to other windows we're involved with.
779 void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
780 {
781 if (m_constraintsInvolvedIn)
782 m_constraintsInvolvedIn->DeleteObject(otherWin);
783 }
784
785 // Reset any constraints that mention this window
786 void wxWindow::DeleteRelatedConstraints()
787 {
788 if (m_constraintsInvolvedIn)
789 {
790 wxNode *node = m_constraintsInvolvedIn->First();
791 while (node)
792 {
793 wxWindow *win = (wxWindow *)node->Data();
794 wxNode *next = node->Next();
795 wxLayoutConstraints *constr = win->GetConstraints();
796
797 // Reset any constraints involving this window
798 if (constr)
799 {
800 constr->left.ResetIfWin((wxWindow *)this);
801 constr->top.ResetIfWin((wxWindow *)this);
802 constr->right.ResetIfWin((wxWindow *)this);
803 constr->bottom.ResetIfWin((wxWindow *)this);
804 constr->width.ResetIfWin((wxWindow *)this);
805 constr->height.ResetIfWin((wxWindow *)this);
806 constr->centreX.ResetIfWin((wxWindow *)this);
807 constr->centreY.ResetIfWin((wxWindow *)this);
808 }
809 delete node;
810 node = next;
811 }
812 delete m_constraintsInvolvedIn;
813 m_constraintsInvolvedIn = NULL;
814 }
815 }
816
817 void wxWindow::SetSizer(wxSizer *sizer)
818 {
819 m_windowSizer = sizer;
820 if (sizer)
821 sizer->SetSizerParent((wxWindow *)this);
822 }
823
824 /*
825 * New version
826 */
827
828 bool wxWindow::Layout()
829 {
830 if (GetConstraints())
831 {
832 int w, h;
833 GetClientSize(&w, &h);
834 GetConstraints()->width.SetValue(w);
835 GetConstraints()->height.SetValue(h);
836 }
837
838 // If top level (one sizer), evaluate the sizer's constraints.
839 if (GetSizer())
840 {
841 int noChanges;
842 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
843 GetSizer()->LayoutPhase1(&noChanges);
844 GetSizer()->LayoutPhase2(&noChanges);
845 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
846 return TRUE;
847 }
848 else
849 {
850 // Otherwise, evaluate child constraints
851 ResetConstraints(); // Mark all constraints as unevaluated
852 DoPhase(1); // Just one phase need if no sizers involved
853 DoPhase(2);
854 SetConstraintSizes(); // Recursively set the real window sizes
855 }
856 return TRUE;
857 }
858
859
860 // Do a phase of evaluating constraints:
861 // the default behaviour. wxSizers may do a similar
862 // thing, but also impose their own 'constraints'
863 // and order the evaluation differently.
864 bool wxWindow::LayoutPhase1(int *noChanges)
865 {
866 wxLayoutConstraints *constr = GetConstraints();
867 if (constr)
868 {
869 return constr->SatisfyConstraints((wxWindow *)this, noChanges);
870 }
871 else
872 return TRUE;
873 }
874
875 bool wxWindow::LayoutPhase2(int *noChanges)
876 {
877 *noChanges = 0;
878
879 // Layout children
880 DoPhase(1);
881 DoPhase(2);
882 return TRUE;
883 }
884
885 // Do a phase of evaluating child constraints
886 bool wxWindow::DoPhase(int phase)
887 {
888 int noIterations = 0;
889 int maxIterations = 500;
890 int noChanges = 1;
891 int noFailures = 0;
892 wxList succeeded;
893 while ((noChanges > 0) && (noIterations < maxIterations))
894 {
895 noChanges = 0;
896 noFailures = 0;
897 wxNode *node = GetChildren().First();
898 while (node)
899 {
900 wxWindow *child = (wxWindow *)node->Data();
901 if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
902 {
903 wxLayoutConstraints *constr = child->GetConstraints();
904 if (constr)
905 {
906 if (succeeded.Member(child))
907 {
908 }
909 else
910 {
911 int tempNoChanges = 0;
912 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
913 noChanges += tempNoChanges;
914 if (success)
915 {
916 succeeded.Append(child);
917 }
918 }
919 }
920 }
921 node = node->Next();
922 }
923 noIterations ++;
924 }
925 return TRUE;
926 }
927
928 void wxWindow::ResetConstraints()
929 {
930 wxLayoutConstraints *constr = GetConstraints();
931 if (constr)
932 {
933 constr->left.SetDone(FALSE);
934 constr->top.SetDone(FALSE);
935 constr->right.SetDone(FALSE);
936 constr->bottom.SetDone(FALSE);
937 constr->width.SetDone(FALSE);
938 constr->height.SetDone(FALSE);
939 constr->centreX.SetDone(FALSE);
940 constr->centreY.SetDone(FALSE);
941 }
942 wxNode *node = GetChildren().First();
943 while (node)
944 {
945 wxWindow *win = (wxWindow *)node->Data();
946 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
947 win->ResetConstraints();
948 node = node->Next();
949 }
950 }
951
952 // Need to distinguish between setting the 'fake' size for
953 // windows and sizers, and setting the real values.
954 void wxWindow::SetConstraintSizes(bool recurse)
955 {
956 wxLayoutConstraints *constr = GetConstraints();
957 if (constr && constr->left.GetDone() && constr->right.GetDone() &&
958 constr->width.GetDone() && constr->height.GetDone())
959 {
960 int x = constr->left.GetValue();
961 int y = constr->top.GetValue();
962 int w = constr->width.GetValue();
963 int h = constr->height.GetValue();
964
965 // If we don't want to resize this window, just move it...
966 if ((constr->width.GetRelationship() != wxAsIs) ||
967 (constr->height.GetRelationship() != wxAsIs))
968 {
969 // Calls Layout() recursively. AAAGH. How can we stop that.
970 // Simply take Layout() out of non-top level OnSizes.
971 SizerSetSize(x, y, w, h);
972 }
973 else
974 {
975 SizerMove(x, y);
976 }
977 }
978 else if (constr)
979 {
980 char *windowClass = this->GetClassInfo()->GetClassName();
981
982 wxString winName;
983 if (GetName() == "")
984 winName = "unnamed";
985 else
986 winName = GetName();
987 wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName);
988 if (!constr->left.GetDone())
989 wxDebugMsg(" unsatisfied 'left' constraint.\n");
990 if (!constr->right.GetDone())
991 wxDebugMsg(" unsatisfied 'right' constraint.\n");
992 if (!constr->width.GetDone())
993 wxDebugMsg(" unsatisfied 'width' constraint.\n");
994 if (!constr->height.GetDone())
995 wxDebugMsg(" unsatisfied 'height' constraint.\n");
996 wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
997 }
998
999 if (recurse)
1000 {
1001 wxNode *node = GetChildren().First();
1002 while (node)
1003 {
1004 wxWindow *win = (wxWindow *)node->Data();
1005 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
1006 win->SetConstraintSizes();
1007 node = node->Next();
1008 }
1009 }
1010 }
1011
1012 // This assumes that all sizers are 'on' the same
1013 // window, i.e. the parent of this window.
1014 void wxWindow::TransformSizerToActual(int *x, int *y) const
1015 {
1016 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
1017 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
1018 return;
1019
1020 int xp, yp;
1021 m_sizerParent->GetPosition(&xp, &yp);
1022 m_sizerParent->TransformSizerToActual(&xp, &yp);
1023 *x += xp;
1024 *y += yp;
1025 }
1026
1027 void wxWindow::SizerSetSize(int x, int y, int w, int h)
1028 {
1029 int xx = x;
1030 int yy = y;
1031 TransformSizerToActual(&xx, &yy);
1032 SetSize(xx, yy, w, h);
1033 }
1034
1035 void wxWindow::SizerMove(int x, int y)
1036 {
1037 int xx = x;
1038 int yy = y;
1039 TransformSizerToActual(&xx, &yy);
1040 Move(xx, yy);
1041 }
1042
1043 // Only set the size/position of the constraint (if any)
1044 void wxWindow::SetSizeConstraint(int x, int y, int w, int h)
1045 {
1046 wxLayoutConstraints *constr = GetConstraints();
1047 if (constr)
1048 {
1049 if (x != -1)
1050 {
1051 constr->left.SetValue(x);
1052 constr->left.SetDone(TRUE);
1053 }
1054 if (y != -1)
1055 {
1056 constr->top.SetValue(y);
1057 constr->top.SetDone(TRUE);
1058 }
1059 if (w != -1)
1060 {
1061 constr->width.SetValue(w);
1062 constr->width.SetDone(TRUE);
1063 }
1064 if (h != -1)
1065 {
1066 constr->height.SetValue(h);
1067 constr->height.SetDone(TRUE);
1068 }
1069 }
1070 }
1071
1072 void wxWindow::MoveConstraint(int x, int y)
1073 {
1074 wxLayoutConstraints *constr = GetConstraints();
1075 if (constr)
1076 {
1077 if (x != -1)
1078 {
1079 constr->left.SetValue(x);
1080 constr->left.SetDone(TRUE);
1081 }
1082 if (y != -1)
1083 {
1084 constr->top.SetValue(y);
1085 constr->top.SetDone(TRUE);
1086 }
1087 }
1088 }
1089
1090 void wxWindow::GetSizeConstraint(int *w, int *h) const
1091 {
1092 wxLayoutConstraints *constr = GetConstraints();
1093 if (constr)
1094 {
1095 *w = constr->width.GetValue();
1096 *h = constr->height.GetValue();
1097 }
1098 else
1099 GetSize(w, h);
1100 }
1101
1102 void wxWindow::GetClientSizeConstraint(int *w, int *h) const
1103 {
1104 wxLayoutConstraints *constr = GetConstraints();
1105 if (constr)
1106 {
1107 *w = constr->width.GetValue();
1108 *h = constr->height.GetValue();
1109 }
1110 else
1111 GetClientSize(w, h);
1112 }
1113
1114 void wxWindow::GetPositionConstraint(int *x, int *y) const
1115 {
1116 wxLayoutConstraints *constr = GetConstraints();
1117 if (constr)
1118 {
1119 *x = constr->left.GetValue();
1120 *y = constr->top.GetValue();
1121 }
1122 else
1123 GetPosition(x, y);
1124 }
1125
1126 bool wxWindow::Close(bool force)
1127 {
1128 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
1129 event.SetEventObject(this);
1130 #if WXWIN_COMPATIBILITY
1131 event.SetForce(force);
1132 #endif
1133 event.SetCanVeto(!force);
1134
1135 return GetEventHandler()->ProcessEvent(event);
1136 }
1137
1138 wxObject* wxWindow::GetChild(int number) const
1139 {
1140 // Return a pointer to the Nth object in the window
1141 wxNode *node = GetChildren().First();
1142 int n = number;
1143 while (node && n--)
1144 node = node->Next() ;
1145 if (node)
1146 {
1147 wxObject *obj = (wxObject *)node->Data();
1148 return(obj) ;
1149 }
1150 else
1151 return NULL ;
1152 }
1153
1154 void wxWindow::OnDefaultAction(wxControl *initiatingItem)
1155 {
1156 // Obsolete function
1157 }
1158
1159 void wxWindow::Clear()
1160 {
1161 wxClientDC dc(this);
1162 wxBrush brush(GetBackgroundColour(), wxSOLID);
1163 dc.SetBackground(brush);
1164 dc.Clear();
1165 }
1166
1167 // Fits the panel around the items
1168 void wxWindow::Fit()
1169 {
1170 int maxX = 0;
1171 int maxY = 0;
1172 wxNode *node = GetChildren().First();
1173 while ( node )
1174 {
1175 wxWindow *win = (wxWindow *)node->Data();
1176 int wx, wy, ww, wh;
1177 win->GetPosition(&wx, &wy);
1178 win->GetSize(&ww, &wh);
1179 if ( wx + ww > maxX )
1180 maxX = wx + ww;
1181 if ( wy + wh > maxY )
1182 maxY = wy + wh;
1183
1184 node = node->Next();
1185 }
1186 SetClientSize(maxX + 5, maxY + 5);
1187 }
1188
1189 void wxWindow::SetValidator(const wxValidator& validator)
1190 {
1191 if ( m_windowValidator )
1192 delete m_windowValidator;
1193 m_windowValidator = validator.Clone();
1194
1195 if ( m_windowValidator )
1196 m_windowValidator->SetWindow(this) ;
1197 }
1198
1199 void wxWindow::SetAcceleratorTable(const wxAcceleratorTable& accel)
1200 {
1201 m_acceleratorTable = accel;
1202 }
1203
1204 // Find a window by id or name
1205 wxWindow *wxWindow::FindWindow(long id)
1206 {
1207 if ( GetId() == id)
1208 return this;
1209
1210 wxNode *node = GetChildren().First();
1211 while ( node )
1212 {
1213 wxWindow *child = (wxWindow *)node->Data();
1214 wxWindow *found = child->FindWindow(id);
1215 if ( found )
1216 return found;
1217 node = node->Next();
1218 }
1219 return NULL;
1220 }
1221
1222 wxWindow *wxWindow::FindWindow(const wxString& name)
1223 {
1224 if ( GetName() == name)
1225 return this;
1226
1227 wxNode *node = GetChildren().First();
1228 while ( node )
1229 {
1230 wxWindow *child = (wxWindow *)node->Data();
1231 wxWindow *found = child->FindWindow(name);
1232 if ( found )
1233 return found;
1234 node = node->Next();
1235 }
1236 return NULL;
1237 }
1238
1239 void wxWindow::OnIdle(wxIdleEvent& event)
1240 {
1241 /* TODO: you may need to do something like this
1242 * if your GUI doesn't generate enter/leave events
1243
1244 // Check if we need to send a LEAVE event
1245 if (m_mouseInWindow)
1246 {
1247 POINT pt;
1248 ::GetCursorPos(&pt);
1249 if (::WindowFromPoint(pt) != (HWND) GetHWND())
1250 {
1251 // Generate a LEAVE event
1252 m_mouseInWindow = FALSE;
1253 MSWOnMouseLeave(pt.x, pt.y, 0);
1254 }
1255 }
1256 */
1257
1258 // This calls the UI-update mechanism (querying windows for
1259 // menu/toolbar/control state information)
1260 UpdateWindowUI();
1261 }
1262
1263 // Raise the window to the top of the Z order
1264 void wxWindow::Raise()
1265 {
1266 // TODO
1267 }
1268
1269 // Lower the window to the bottom of the Z order
1270 void wxWindow::Lower()
1271 {
1272 // TODO
1273 }
1274
1275 bool wxWindow::AcceptsFocus() const
1276 {
1277 return IsShown() && IsEnabled();
1278 }
1279
1280 // Update region access
1281 wxRegion wxWindow::GetUpdateRegion() const
1282 {
1283 return m_updateRegion;
1284 }
1285
1286 bool wxWindow::IsExposed(int x, int y, int w, int h) const
1287 {
1288 return (m_updateRegion.Contains(x, y, w, h) != wxOutRegion);
1289 }
1290
1291 bool wxWindow::IsExposed(const wxPoint& pt) const
1292 {
1293 return (m_updateRegion.Contains(pt) != wxOutRegion);
1294 }
1295
1296 bool wxWindow::IsExposed(const wxRect& rect) const
1297 {
1298 return (m_updateRegion.Contains(rect) != wxOutRegion);
1299 }
1300
1301 void wxWindow::SetToolTip(const wxString& tooltip)
1302 {
1303 // TODO
1304 }
1305
1306 /*
1307 * Allocates control IDs
1308 */
1309
1310 int wxWindow::NewControlId()
1311 {
1312 static int s_controlId = 0;
1313 s_controlId ++;
1314 return s_controlId;
1315 }
1316
1317