1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "window.h"
19 #include "wx/dcclient.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"
31 #include "wx/menuitem.h"
39 #include "wx/motif/private.h"
43 extern wxList wxPendingDelete
;
45 #if !USE_SHARED_LIBRARY
46 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxEvtHandler
)
48 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
49 EVT_CHAR(wxWindow::OnChar
)
50 EVT_ERASE_BACKGROUND(wxWindow::OnEraseBackground
)
51 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
52 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
53 EVT_IDLE(wxWindow::OnIdle
)
65 m_windowParent
= NULL
;
66 m_windowEventHandler
= this;
68 m_windowCursor
= *wxSTANDARD_CURSOR
;
69 m_children
= new wxList
;
71 m_constraintsInvolvedIn
= NULL
;
75 m_windowValidator
= NULL
;
78 m_caretWidth
= 0; m_caretHeight
= 0;
79 m_caretEnabled
= FALSE
;
81 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW
) ; ;
82 m_foregroundColour
= *wxBLACK
;
83 m_defaultForegroundColour
= *wxBLACK
;
84 m_defaultBackgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
) ;
91 m_mainWidget
= (WXWidget
) 0;
92 m_button1Pressed
= FALSE
;
93 m_button2Pressed
= FALSE
;
94 m_button3Pressed
= FALSE
;
95 m_winCaptured
= FALSE
;
100 wxWindow::~wxWindow()
102 // Have to delete constraints/sizer FIRST otherwise
103 // sizers may try to look at deleted windows as they
104 // delete themselves.
106 DeleteRelatedConstraints();
109 // This removes any dangling pointers to this window
110 // in other windows' constraintsInvolvedIn lists.
111 UnsetConstraints(m_constraints
);
112 delete m_constraints
;
113 m_constraints
= NULL
;
117 delete m_windowSizer
;
118 m_windowSizer
= NULL
;
120 // If this is a child of a sizer, remove self from parent
122 m_sizerParent
->RemoveChild((wxWindow
*)this);
126 m_windowParent
->RemoveChild(this);
130 // Destroy the window
133 wxDeleteWindowFromTable((Widget
) GetMainWidget());
134 XtDestroyWidget((Widget
) GetMainWidget());
135 SetMainWidget((WXWidget
) NULL
);
141 // Just in case the window has been Closed, but
142 // we're then deleting immediately: don't leave
143 // dangling pointers.
144 wxPendingDelete
.DeleteObject(this);
146 if ( m_windowValidator
)
147 delete m_windowValidator
;
150 // Destroy the window (delayed, if a managed window)
151 bool wxWindow::Destroy()
158 bool wxWindow::Create(wxWindow
*parent
, wxWindowID id
,
162 const wxString
& name
)
167 m_windowParent
= NULL
;
168 m_windowEventHandler
= this;
170 m_windowCursor
= *wxSTANDARD_CURSOR
;
171 m_constraints
= NULL
;
172 m_constraintsInvolvedIn
= NULL
;
173 m_windowSizer
= NULL
;
174 m_sizerParent
= NULL
;
175 m_autoLayout
= FALSE
;
176 m_windowValidator
= NULL
;
178 #if USE_DRAG_AND_DROP
179 m_pDropTarget
= NULL
;
182 m_caretWidth
= 0; m_caretHeight
= 0;
183 m_caretEnabled
= FALSE
;
184 m_caretShown
= FALSE
;
189 m_defaultItem
= NULL
;
190 m_windowParent
= NULL
;
194 if (parent
) parent
->AddChild(this);
201 m_windowId
= (int)NewControlId();
205 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW
) ; ;
206 m_foregroundColour
= *wxBLACK
;
207 m_defaultForegroundColour
= *wxBLACK
;
208 m_defaultBackgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
) ;
210 m_windowStyle
= style
;
213 m_windowId
= (int)NewControlId();
217 // TODO: create the window
222 void wxWindow::SetFocus()
224 XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
);
225 XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
);
228 void wxWindow::Enable(bool enable
)
232 XtSetSensitive((Widget
) GetMainWidget(), enable
);
233 XmUpdateDisplay((Widget
) GetMainWidget());
237 void wxWindow::CaptureMouse()
243 XtAddGrab((Widget
) GetMainWidget(), TRUE
, FALSE
);
245 m_winCaptured
= TRUE
;
248 void wxWindow::ReleaseMouse()
254 XtRemoveGrab((Widget
) GetMainWidget());
255 m_winCaptured
= FALSE
;
258 // Push/pop event handler (i.e. allow a chain of event handlers
260 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
262 handler
->SetNextHandler(GetEventHandler());
263 SetEventHandler(handler
);
266 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
268 if ( GetEventHandler() )
270 wxEvtHandler
*handlerA
= GetEventHandler();
271 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
272 handlerA
->SetNextHandler(NULL
);
273 SetEventHandler(handlerB
);
286 #if USE_DRAG_AND_DROP
288 void wxWindow::SetDropTarget(wxDropTarget
*pDropTarget
)
290 if ( m_pDropTarget
!= 0 ) {
291 delete m_pDropTarget
;
294 m_pDropTarget
= pDropTarget
;
295 if ( m_pDropTarget
!= 0 )
303 // Old style file-manager drag&drop
304 void wxWindow::DragAcceptFiles(bool accept
)
310 void wxWindow::GetSize(int *x
, int *y
) const
312 Widget widget
= (Widget
) GetMainWidget();
314 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
318 void wxWindow::GetPosition(int *x
, int *y
) const
320 Widget widget
= (Widget
) GetMainWidget();
322 XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
326 void wxWindow::ScreenToClient(int *x
, int *y
) const
331 void wxWindow::ClientToScreen(int *x
, int *y
) const
333 Widget widget
= (Widget
) GetMainWidget();
334 Display
*display
= XtDisplay(widget
);
335 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
337 if (this->IsKindOf(CLASSINFO(wxFrame
)))
339 wxFrame
*fr
= (wxFrame
*)this;
341 // thisWindow = XtWindow(fr->m_clientArea);
344 thisWindow
= XtWindow((Widget
)widget
);
349 XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
);
352 void wxWindow::SetCursor(const wxCursor
& cursor
)
354 m_windowCursor
= cursor
;
355 if (m_windowCursor
.Ok())
357 /* TODO when wxCursor implemented
358 WXDisplay *dpy = GetXDisplay();
359 Cursor x_cursor = cursor.GetXCursor(dpy);
361 Widget w = (Widget) GetMainWidget();
362 Window win = XtWindow(w);
363 XDefineCursor((Display*) dpy, win, x_cursor);
369 // Get size *available for subwindows* i.e. excluding menu bar etc.
370 void wxWindow::GetClientSize(int *x
, int *y
) const
372 Widget widget
= (Widget
) GetMainWidget();
374 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
378 void wxWindow::SetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
380 Widget widget
= (Widget
) GetMainWidget();
382 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
383 XtVaSetValues(widget
, XmNx
, x
, NULL
);
384 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
385 XtVaSetValues(widget
, XmNy
, y
, NULL
);
387 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
389 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
391 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
392 sizeEvent
.SetEventObject(this);
394 GetEventHandler()->ProcessEvent(sizeEvent
);
397 void wxWindow::SetClientSize(int width
, int height
)
399 Widget widget
= (Widget
) GetMainWidget();
402 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
404 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
406 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
407 sizeEvent
.SetEventObject(this);
409 GetEventHandler()->ProcessEvent(sizeEvent
);
412 // For implementation purposes - sometimes decorations make the client area
414 wxPoint
wxWindow::GetClientAreaOrigin() const
416 return wxPoint(0, 0);
419 // Makes an adjustment to the window position (for example, a frame that has
420 // a toolbar that it manages itself).
421 void wxWindow::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
)
423 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
425 wxPoint
pt(GetParent()->GetClientAreaOrigin());
426 x
+= pt
.x
; y
+= pt
.y
;
430 bool wxWindow::Show(bool show
)
432 Window xwin
= (Window
) GetXWindow();
433 Display
*xdisp
= (Display
*) GetXDisplay();
435 XMapWindow(xdisp
, xwin
);
437 XUnmapWindow(xdisp
, xwin
);
444 bool wxWindow::IsShown() const
449 int wxWindow::GetCharHeight() const
455 int wxWindow::GetCharWidth() const
461 void wxWindow::GetTextExtent(const wxString
& string
, int *x
, int *y
,
462 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool) const
464 wxFont
*fontToUse
= (wxFont
*)theFont
;
466 fontToUse
= (wxFont
*) & m_windowFont
;
471 void wxWindow::Refresh(bool eraseBack
, const wxRectangle
*rect
)
473 Display
*display
= XtDisplay((Widget
) GetMainWidget());
474 Window thisWindow
= XtWindow((Widget
) GetMainWidget());
476 XExposeEvent dummyEvent
;
478 GetSize(&width
, &height
);
480 dummyEvent
.type
= Expose
;
481 dummyEvent
.display
= display
;
482 dummyEvent
.send_event
= True
;
483 dummyEvent
.window
= thisWindow
;
486 dummyEvent
.x
= rect
->x
;
487 dummyEvent
.y
= rect
->y
;
488 dummyEvent
.width
= rect
->width
;
489 dummyEvent
.height
= rect
->height
;
495 dummyEvent
.width
= width
;
496 dummyEvent
.height
= height
;
498 dummyEvent
.count
= 0;
506 XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent
*)&dummyEvent
);
509 // Responds to colour changes: passes event on to children.
510 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
)
512 wxNode
*node
= GetChildren()->First();
515 // Only propagate to non-top-level windows
516 wxWindow
*win
= (wxWindow
*)node
->Data();
517 if ( win
->GetParent() )
519 wxSysColourChangedEvent event2
;
520 event
.m_eventObject
= win
;
521 win
->GetEventHandler()->ProcessEvent(event2
);
528 // This can be called by the app (or wxWindows) to do default processing for the current
529 // event. Save message/event info in wxWindow so they can be used in this function.
530 long wxWindow::Default()
536 void wxWindow::InitDialog()
538 wxInitDialogEvent
event(GetId());
539 event
.SetEventObject( this );
540 GetEventHandler()->ProcessEvent(event
);
543 // Default init dialog behaviour is to transfer data to window
544 void wxWindow::OnInitDialog(wxInitDialogEvent
& event
)
546 TransferDataToWindow();
549 // Caret manipulation
550 void wxWindow::CreateCaret(int w
, int h
)
554 m_caretEnabled
= TRUE
;
557 void wxWindow::CreateCaret(const wxBitmap
*WXUNUSED(bitmap
))
562 void wxWindow::ShowCaret(bool show
)
567 void wxWindow::DestroyCaret()
570 m_caretEnabled
= FALSE
;
573 void wxWindow::SetCaretPos(int x
, int y
)
578 void wxWindow::GetCaretPos(int *x
, int *y
) const
583 wxWindow
*wxGetActiveWindow()
589 void wxWindow::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
)
596 if (!this->IsKindOf(CLASSINFO(wxFrame
)))
599 wxFrame
*frame
= (wxFrame
*)this;
601 /* Uncomment when wxFrame implemented
603 XtVaSetValues((Widget) frame->m_frameShell, XmNminWidth, minW, NULL);
605 XtVaSetValues((Widget) frame->m_frameShell, XmNminHeight, minH, NULL);
607 XtVaSetValues((Widget) frame->m_frameShell, XmNmaxWidth, maxW, NULL);
609 XtVaSetValues((Widget) frame->m_frameShell, XmNmaxHeight, maxH, NULL);
611 XtVaSetValues((Widget) frame->m_frameShell, XmNwidthInc, incW, NULL);
613 XtVaSetValues((Widget) frame->m_frameShell, XmNheightInc, incH, NULL);
617 void wxWindow::Centre(int direction
)
619 int x
, y
, width
, height
, panel_width
, panel_height
, new_x
, new_y
;
621 wxWindow
*father
= (wxWindow
*)GetParent();
625 father
->GetClientSize(&panel_width
, &panel_height
);
626 GetSize(&width
, &height
);
632 if (direction
& wxHORIZONTAL
)
633 new_x
= (int)((panel_width
- width
)/2);
635 if (direction
& wxVERTICAL
)
636 new_y
= (int)((panel_height
- height
)/2);
638 SetSize(new_x
, new_y
, -1, -1);
642 // Coordinates relative to the window
643 void wxWindow::WarpPointer (int x_pos
, int y_pos
)
648 void wxWindow::OnEraseBackground(wxEraseEvent
& event
)
654 int wxWindow::GetScrollPos(int orient
) const
660 // This now returns the whole range, not just the number
661 // of positions that we can scroll.
662 int wxWindow::GetScrollRange(int orient
) const
668 int wxWindow::GetScrollThumb(int orient
) const
674 void wxWindow::SetScrollPos(int orient
, int pos
, bool refresh
)
680 // New function that will replace some of the above.
681 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
,
682 int range
, bool refresh
)
687 // Does a physical scroll
688 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRectangle
*rect
)
694 void wxWindow::SetFont(const wxFont
& font
)
698 if (!m_windowFont
.Ok())
703 void wxWindow::OnChar(wxKeyEvent
& event
)
705 if ( event
.KeyCode() == WXK_TAB
) {
706 // propagate the TABs to the parent - it's up to it to decide what
709 if ( GetParent()->ProcessEvent(event
) )
715 void wxWindow::OnPaint(wxPaintEvent
& event
)
720 bool wxWindow::IsEnabled() const
726 // Dialog support: override these and call
727 // base class members to add functionality
728 // that can't be done using validators.
729 // NOTE: these functions assume that controls
730 // are direct children of this window, not grandchildren
731 // or other levels of descendant.
733 // Transfer values to controls. If returns FALSE,
734 // it's an application error (pops up a dialog)
735 bool wxWindow::TransferDataToWindow()
737 wxNode
*node
= GetChildren()->First();
740 wxWindow
*child
= (wxWindow
*)node
->Data();
741 if ( child
->GetValidator() &&
742 !child
->GetValidator()->TransferToWindow() )
744 wxMessageBox("Application Error", "Could not transfer data to window", wxOK
|wxICON_EXCLAMATION
);
753 // Transfer values from controls. If returns FALSE,
754 // validation failed: don't quit
755 bool wxWindow::TransferDataFromWindow()
757 wxNode
*node
= GetChildren()->First();
760 wxWindow
*child
= (wxWindow
*)node
->Data();
761 if ( child
->GetValidator() && !child
->GetValidator()->TransferFromWindow() )
771 bool wxWindow::Validate()
773 wxNode
*node
= GetChildren()->First();
776 wxWindow
*child
= (wxWindow
*)node
->Data();
777 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this) )
787 // Get the window with the focus
788 wxWindow
*wxWindow::FindFocus()
794 void wxWindow::AddChild(wxWindow
*child
)
796 GetChildren()->Append(child
);
797 child
->m_windowParent
= this;
800 void wxWindow::RemoveChild(wxWindow
*child
)
803 GetChildren()->DeleteObject(child
);
804 child
->m_windowParent
= NULL
;
807 void wxWindow::DestroyChildren()
811 while ((node
= GetChildren()->First()) != (wxNode
*)NULL
) {
813 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
) {
815 if ( GetChildren()->Member(child
) )
822 void wxWindow::MakeModal(bool modal
)
824 // Disable all other windows
825 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
827 wxNode
*node
= wxTopLevelWindows
.First();
830 wxWindow
*win
= (wxWindow
*)node
->Data();
839 void wxWindow::SetConstraints(wxLayoutConstraints
*c
)
843 UnsetConstraints(m_constraints
);
844 delete m_constraints
;
849 // Make sure other windows know they're part of a 'meaningful relationship'
850 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
851 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
852 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
853 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
854 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
855 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
856 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
857 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
858 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
859 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
860 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
861 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
862 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
863 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
864 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
865 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
869 // This removes any dangling pointers to this window
870 // in other windows' constraintsInvolvedIn lists.
871 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
875 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
876 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
877 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
878 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
879 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
880 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
881 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
882 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
883 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
884 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
885 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
886 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
887 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
888 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
889 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
890 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
894 // Back-pointer to other windows we're involved with, so if we delete
895 // this window, we must delete any constraints we're involved with.
896 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
898 if (!m_constraintsInvolvedIn
)
899 m_constraintsInvolvedIn
= new wxList
;
900 if (!m_constraintsInvolvedIn
->Member(otherWin
))
901 m_constraintsInvolvedIn
->Append(otherWin
);
904 // REMOVE back-pointer to other windows we're involved with.
905 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
907 if (m_constraintsInvolvedIn
)
908 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
911 // Reset any constraints that mention this window
912 void wxWindow::DeleteRelatedConstraints()
914 if (m_constraintsInvolvedIn
)
916 wxNode
*node
= m_constraintsInvolvedIn
->First();
919 wxWindow
*win
= (wxWindow
*)node
->Data();
920 wxNode
*next
= node
->Next();
921 wxLayoutConstraints
*constr
= win
->GetConstraints();
923 // Reset any constraints involving this window
926 constr
->left
.ResetIfWin((wxWindow
*)this);
927 constr
->top
.ResetIfWin((wxWindow
*)this);
928 constr
->right
.ResetIfWin((wxWindow
*)this);
929 constr
->bottom
.ResetIfWin((wxWindow
*)this);
930 constr
->width
.ResetIfWin((wxWindow
*)this);
931 constr
->height
.ResetIfWin((wxWindow
*)this);
932 constr
->centreX
.ResetIfWin((wxWindow
*)this);
933 constr
->centreY
.ResetIfWin((wxWindow
*)this);
938 delete m_constraintsInvolvedIn
;
939 m_constraintsInvolvedIn
= NULL
;
943 void wxWindow::SetSizer(wxSizer
*sizer
)
945 m_windowSizer
= sizer
;
947 sizer
->SetSizerParent((wxWindow
*)this);
954 bool wxWindow::Layout()
956 if (GetConstraints())
959 GetClientSize(&w
, &h
);
960 GetConstraints()->width
.SetValue(w
);
961 GetConstraints()->height
.SetValue(h
);
964 // If top level (one sizer), evaluate the sizer's constraints.
968 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
969 GetSizer()->LayoutPhase1(&noChanges
);
970 GetSizer()->LayoutPhase2(&noChanges
);
971 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
976 // Otherwise, evaluate child constraints
977 ResetConstraints(); // Mark all constraints as unevaluated
978 DoPhase(1); // Just one phase need if no sizers involved
980 SetConstraintSizes(); // Recursively set the real window sizes
986 // Do a phase of evaluating constraints:
987 // the default behaviour. wxSizers may do a similar
988 // thing, but also impose their own 'constraints'
989 // and order the evaluation differently.
990 bool wxWindow::LayoutPhase1(int *noChanges
)
992 wxLayoutConstraints
*constr
= GetConstraints();
995 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
1001 bool wxWindow::LayoutPhase2(int *noChanges
)
1011 // Do a phase of evaluating child constraints
1012 bool wxWindow::DoPhase(int phase
)
1014 int noIterations
= 0;
1015 int maxIterations
= 500;
1019 while ((noChanges
> 0) && (noIterations
< maxIterations
))
1023 wxNode
*node
= GetChildren()->First();
1026 wxWindow
*child
= (wxWindow
*)node
->Data();
1027 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
1029 wxLayoutConstraints
*constr
= child
->GetConstraints();
1032 if (succeeded
.Member(child
))
1037 int tempNoChanges
= 0;
1038 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
1039 noChanges
+= tempNoChanges
;
1042 succeeded
.Append(child
);
1047 node
= node
->Next();
1054 void wxWindow::ResetConstraints()
1056 wxLayoutConstraints
*constr
= GetConstraints();
1059 constr
->left
.SetDone(FALSE
);
1060 constr
->top
.SetDone(FALSE
);
1061 constr
->right
.SetDone(FALSE
);
1062 constr
->bottom
.SetDone(FALSE
);
1063 constr
->width
.SetDone(FALSE
);
1064 constr
->height
.SetDone(FALSE
);
1065 constr
->centreX
.SetDone(FALSE
);
1066 constr
->centreY
.SetDone(FALSE
);
1068 wxNode
*node
= GetChildren()->First();
1071 wxWindow
*win
= (wxWindow
*)node
->Data();
1072 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
1073 win
->ResetConstraints();
1074 node
= node
->Next();
1078 // Need to distinguish between setting the 'fake' size for
1079 // windows and sizers, and setting the real values.
1080 void wxWindow::SetConstraintSizes(bool recurse
)
1082 wxLayoutConstraints
*constr
= GetConstraints();
1083 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
1084 constr
->width
.GetDone() && constr
->height
.GetDone())
1086 int x
= constr
->left
.GetValue();
1087 int y
= constr
->top
.GetValue();
1088 int w
= constr
->width
.GetValue();
1089 int h
= constr
->height
.GetValue();
1091 // If we don't want to resize this window, just move it...
1092 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
1093 (constr
->height
.GetRelationship() != wxAsIs
))
1095 // Calls Layout() recursively. AAAGH. How can we stop that.
1096 // Simply take Layout() out of non-top level OnSizes.
1097 SizerSetSize(x
, y
, w
, h
);
1106 char *windowClass
= this->GetClassInfo()->GetClassName();
1109 if (GetName() == "")
1110 winName
= "unnamed";
1112 winName
= GetName();
1113 wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass
, (const char *)winName
);
1114 if (!constr
->left
.GetDone())
1115 wxDebugMsg(" unsatisfied 'left' constraint.\n");
1116 if (!constr
->right
.GetDone())
1117 wxDebugMsg(" unsatisfied 'right' constraint.\n");
1118 if (!constr
->width
.GetDone())
1119 wxDebugMsg(" unsatisfied 'width' constraint.\n");
1120 if (!constr
->height
.GetDone())
1121 wxDebugMsg(" unsatisfied 'height' constraint.\n");
1122 wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
1127 wxNode
*node
= GetChildren()->First();
1130 wxWindow
*win
= (wxWindow
*)node
->Data();
1131 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
1132 win
->SetConstraintSizes();
1133 node
= node
->Next();
1138 // This assumes that all sizers are 'on' the same
1139 // window, i.e. the parent of this window.
1140 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
1142 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
1143 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
1147 m_sizerParent
->GetPosition(&xp
, &yp
);
1148 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
1153 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
1157 TransformSizerToActual(&xx
, &yy
);
1158 SetSize(xx
, yy
, w
, h
);
1161 void wxWindow::SizerMove(int x
, int y
)
1165 TransformSizerToActual(&xx
, &yy
);
1169 // Only set the size/position of the constraint (if any)
1170 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
1172 wxLayoutConstraints
*constr
= GetConstraints();
1177 constr
->left
.SetValue(x
);
1178 constr
->left
.SetDone(TRUE
);
1182 constr
->top
.SetValue(y
);
1183 constr
->top
.SetDone(TRUE
);
1187 constr
->width
.SetValue(w
);
1188 constr
->width
.SetDone(TRUE
);
1192 constr
->height
.SetValue(h
);
1193 constr
->height
.SetDone(TRUE
);
1198 void wxWindow::MoveConstraint(int x
, int y
)
1200 wxLayoutConstraints
*constr
= GetConstraints();
1205 constr
->left
.SetValue(x
);
1206 constr
->left
.SetDone(TRUE
);
1210 constr
->top
.SetValue(y
);
1211 constr
->top
.SetDone(TRUE
);
1216 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
1218 wxLayoutConstraints
*constr
= GetConstraints();
1221 *w
= constr
->width
.GetValue();
1222 *h
= constr
->height
.GetValue();
1228 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
1230 wxLayoutConstraints
*constr
= GetConstraints();
1233 *w
= constr
->width
.GetValue();
1234 *h
= constr
->height
.GetValue();
1237 GetClientSize(w
, h
);
1240 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
1242 wxLayoutConstraints
*constr
= GetConstraints();
1245 *x
= constr
->left
.GetValue();
1246 *y
= constr
->top
.GetValue();
1252 bool wxWindow::Close(bool force
)
1254 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1255 event
.SetEventObject(this);
1256 event
.SetForce(force
);
1258 return GetEventHandler()->ProcessEvent(event
);
1261 wxObject
* wxWindow::GetChild(int number
) const
1263 // Return a pointer to the Nth object in the window
1266 wxNode
*node
= GetChildren()->First();
1269 node
= node
->Next() ;
1272 wxObject
*obj
= (wxObject
*)node
->Data();
1279 void wxWindow::OnDefaultAction(wxControl
*initiatingItem
)
1281 // Obsolete function
1284 void wxWindow::Clear()
1286 wxClientDC
dc(this);
1287 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
1288 dc
.SetBackground(brush
);
1292 // Fits the panel around the items
1293 void wxWindow::Fit()
1297 wxNode
*node
= GetChildren()->First();
1300 wxWindow
*win
= (wxWindow
*)node
->Data();
1302 win
->GetPosition(&wx
, &wy
);
1303 win
->GetSize(&ww
, &wh
);
1304 if ( wx
+ ww
> maxX
)
1306 if ( wy
+ wh
> maxY
)
1309 node
= node
->Next();
1311 SetClientSize(maxX
+ 5, maxY
+ 5);
1314 void wxWindow::SetValidator(const wxValidator
& validator
)
1316 if ( m_windowValidator
)
1317 delete m_windowValidator
;
1318 m_windowValidator
= validator
.Clone();
1320 if ( m_windowValidator
)
1321 m_windowValidator
->SetWindow(this) ;
1324 // Find a window by id or name
1325 wxWindow
*wxWindow::FindWindow(long id
)
1330 wxNode
*node
= GetChildren()->First();
1333 wxWindow
*child
= (wxWindow
*)node
->Data();
1334 wxWindow
*found
= child
->FindWindow(id
);
1337 node
= node
->Next();
1342 wxWindow
*wxWindow::FindWindow(const wxString
& name
)
1344 if ( GetName() == name
)
1347 wxNode
*node
= GetChildren()->First();
1350 wxWindow
*child
= (wxWindow
*)node
->Data();
1351 wxWindow
*found
= child
->FindWindow(name
);
1354 node
= node
->Next();
1359 void wxWindow::OnIdle(wxIdleEvent
& event
)
1361 /* TODO: you may need to do something like this
1362 * if your GUI doesn't generate enter/leave events
1364 // Check if we need to send a LEAVE event
1365 if (m_mouseInWindow)
1368 ::GetCursorPos(&pt);
1369 if (::WindowFromPoint(pt) != (HWND) GetHWND())
1371 // Generate a LEAVE event
1372 m_mouseInWindow = FALSE;
1373 MSWOnMouseLeave(pt.x, pt.y, 0);
1378 // This calls the UI-update mechanism (querying windows for
1379 // menu/toolbar/control state information)
1383 // Raise the window to the top of the Z order
1384 void wxWindow::Raise()
1386 Window window
= XtWindow((Widget
) GetMainWidget());
1387 XRaiseWindow(XtDisplay((Widget
) GetMainWidget()), window
);
1390 // Lower the window to the bottom of the Z order
1391 void wxWindow::Lower()
1393 Window window
= XtWindow((Widget
) GetMainWidget());
1394 XLowerWindow(XtDisplay((Widget
) GetMainWidget()), window
);
1397 bool wxWindow::AcceptsFocus() const
1399 return IsShown() && IsEnabled();
1402 // Update region access
1403 wxRegion
wxWindow::GetUpdateRegion() const
1405 return m_updateRegion
;
1408 bool wxWindow::IsExposed(int x
, int y
, int w
, int h
) const
1410 return (m_updateRegion
.Contains(x
, y
, w
, h
) != wxOutRegion
);
1413 bool wxWindow::IsExposed(const wxPoint
& pt
) const
1415 return (m_updateRegion
.Contains(pt
) != wxOutRegion
);
1418 bool wxWindow::IsExposed(const wxRect
& rect
) const
1420 return (m_updateRegion
.Contains(rect
) != wxOutRegion
);
1424 * Allocates control IDs
1427 int wxWindow::NewControlId()
1429 static int s_controlId
= 0;
1434 void wxWindow::SetAcceleratorTable(const wxAcceleratorTable
& accel
)
1436 m_acceleratorTable
= accel
;
1439 // All widgets should have this as their resize proc.
1440 // OnSize sent to wxWindow via client data.
1441 void wxWidgetResizeProc(Widget w
, XConfigureEvent
*event
, String args
[], int *num_args
)
1443 wxWindow
*win
= (wxWindow
*)wxWidgetHashTable
->Get((long)w
);
1447 if (win
->PreResize())
1450 win
->GetSize(&width
, &height
);
1451 wxSizeEvent
sizeEvent(wxSize(width
, height
), win
->GetId());
1452 sizeEvent
.SetEventObject(win
);
1453 win
->GetEventHandler()->ProcessEvent(sizeEvent
);
1457 bool wxAddWindowToTable(Widget w
, wxWindow
*win
)
1459 wxWindow
*oldItem
= NULL
;
1461 // printf("Adding widget %ld, name = %s\n", w, win->GetClassInfo()->GetClassName());
1463 if ((oldItem
= (wxWindow
*)wxWidgetHashTable
->Get ((long) w
)))
1466 sprintf(buf
, "Widget table clash: new widget is %ld, %s", (long)w
, win
->GetClassInfo()->GetClassName());
1469 sprintf(buf
, "Old widget was %s", oldItem
->GetClassInfo()->GetClassName());
1474 wxWidgetHashTable
->Put ((long) w
, win
);
1478 wxWindow
*wxGetWindowFromTable(Widget w
)
1480 return (wxWindow
*)wxWidgetHashTable
->Get ((long) w
);
1483 void wxDeleteWindowFromTable(Widget w
)
1486 // printf("Deleting widget %ld\n", w);
1488 // wxWindow *win = (wxWindow *)wxWidgetHashTable->Get ((long) w);
1490 wxWidgetHashTable
->Delete((long)w
);
1493 // Get the underlying X window and display
1494 WXWindow
wxWindow::GetXWindow() const
1496 return (WXWindow
) XtWindow((Widget
) GetMainWidget());
1499 WXDisplay
*wxWindow::GetXDisplay() const
1501 return (WXDisplay
*) XtDisplay((Widget
) GetMainWidget());
1504 WXWidget
wxWindow::GetMainWidget() const
1506 return m_mainWidget
;