1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "window.h"
16 #include "wx/window.h"
20 #include "wx/layout.h"
22 #include "wx/dialog.h"
23 #include "wx/msgdlg.h"
24 #include "wx/dcclient.h"
27 #include "wx/statusbr.h"
29 #include "wx/settings.h"
31 #include "gdk/gdkprivate.h"
32 #include "gdk/gdkkeysyms.h"
36 //-----------------------------------------------------------------------------
37 // documentation on internals
38 //-----------------------------------------------------------------------------
41 I have been asked several times about writing some documentation about
42 the GTK port of wxWindows, especially its internal structures. Obviously,
43 you cannot understand wxGTK without knowing a little about the GTK, but
44 some more information about what the wxWindow, which is the base class
45 for all other window classes, does seems required as well.
47 What does wxWindow do? It contains the common interface for the following
48 jobs of its descendants:
50 1) Define the rudimentary behaviour common to all window classes, such as
51 resizing, intercepting user input (so as to make it possible to use these
52 events for special purposes in a derived class), window names etc.
54 2) Provide the possibility to contain and manage children, if the derived
55 class is allowed to contain children, which holds true for those window
56 classes which do not display a native GTK widget. To name them, these
57 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
58 work classes are a special case and are handled a bit differently from
59 the rest. The same holds true for the wxNotebook class.
61 3) Provide the possibility to draw into a client area of a window. This,
62 too, only holds true for classes that do not display a native GTK widget
65 4) Provide the entire mechanism for scrolling widgets. This actual inter-
66 face for this is usually in wxScrolledWindow, but the GTK implementation
69 5) A multitude of helper or extra methods for special purposes, such as
70 Drag'n'Drop, managing validators etc.
72 Normally one might expect, that one wxWindows window would always correspond
73 to one GTK widget. Under GTK, there is no such allround widget that has all
74 the functionality. Moreover, the GTK defines a client area as a different
75 widget from the actual widget you are handling. Last but not least some
76 special classes (e.g. wxFrame) handle different categories of widgets and
77 still have the possibility to draw something in the client area.
78 It was therefore required to write a special purpose GTK widget, that would
79 represent a client area in the sense of wxWindows capable to do the jobs
80 2), 3) and 4). I have written this class and it resides in win_gtk.c of
83 All windows must have a widget, with which they interact with other under-
84 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
85 thw wxWindow class has a member variable called m_widget which holds a
86 pointer to this widget. When the window class represents a GTK native widget,
87 this is (in most cases) the only GTK widget the class manages. E.g. the
88 wxStatitText class handles only a GtkLabel widget a pointer to which you
89 can find in m_widget (defined in wxWindow)
91 When the class has a client area for drawing into and for containing children
92 it has to handle the client area widget (of the type GtkMyFixed, defined in
93 win_gtk.c), but there could be any number of widgets, handled by a class
94 The common rule for all windows is only, that the widget that interacts with
95 the rest of GTK must be referenced in m_widget and all other widgets must be
96 children of this widget on the GTK level. The top-most widget, which also
97 represents the client area, must be in the m_wxwindow field and must be of
100 As I said, the window classes that display a GTK native widget only have
101 one widget, so in the case of e.g. the wxButton class m_widget holds a
102 pointer to a GtkButton widget. But windows with client areas (for drawing
103 and children) have a m_widget field that is a pointer to a GtkScrolled-
104 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
105 one is (in the GTK sense) a child of the GtkScrolledWindow.
107 If the m_wxwindow field is set, then all input to this widget is inter-
108 cepted and sent to the wxWindows class. If not, all input to the widget
109 that gets pointed to by m_widget gets intercepted and sent to the class.
113 //-------------------------------------------------------------------------
114 // conditional compilation
115 //-------------------------------------------------------------------------
117 #if (GTK_MINOR_VERSION == 1)
118 #if (GTK_MICRO_VERSION >= 5)
119 #define NEW_GTK_SCROLL_CODE
123 //-----------------------------------------------------------------------------
125 //-----------------------------------------------------------------------------
127 extern wxList wxPendingDelete
;
128 extern wxList wxTopLevelWindows
;
129 extern bool g_blockEventsOnDrag
;
130 extern bool g_blockEventsOnScroll
;
131 static bool g_capturing
= FALSE
;
133 // hack: we need something to pass to gtk_menu_popup, so we store the time of
134 // the last click here
135 static guint32 gs_timeLastClick
= 0;
137 //-----------------------------------------------------------------------------
138 // "expose_event" (of m_wxwindow, not of m_widget)
139 //-----------------------------------------------------------------------------
141 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
143 if (!win
->HasVMT()) return;
145 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
147 gdk_event
->area
.width
,
148 gdk_event
->area
.height
);
150 if (gdk_event
->count
> 0) return;
153 printf( "OnExpose from " );
154 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
155 printf( win->GetClassInfo()->GetClassName() );
159 wxPaintEvent
event( win
->GetId() );
160 event
.SetEventObject( win
);
161 win
->GetEventHandler()->ProcessEvent( event
);
163 win
->m_updateRegion
.Clear();
166 //-----------------------------------------------------------------------------
167 // "draw" (of m_wxwindow, not of m_widget)
168 //-----------------------------------------------------------------------------
170 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
172 if (!win
->HasVMT()) return;
174 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
176 wxPaintEvent
event( win
->GetId() );
177 event
.SetEventObject( win
);
178 win
->GetEventHandler()->ProcessEvent( event
);
180 win
->m_updateRegion
.Clear();
183 //-----------------------------------------------------------------------------
185 //-----------------------------------------------------------------------------
187 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
189 if (!win
->HasVMT()) return FALSE
;
190 if (g_blockEventsOnDrag
) return FALSE
;
193 printf( "OnKeyPress from " );
194 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
195 printf( win->GetClassInfo()->GetClassName() );
200 switch (gdk_event
->keyval
)
202 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
203 case GDK_Tab
: key_code
= WXK_TAB
; break;
204 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
205 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
206 case GDK_Return
: key_code
= WXK_RETURN
; break;
207 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
208 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
209 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
210 case GDK_Delete
: key_code
= WXK_DELETE
; break;
211 case GDK_Home
: key_code
= WXK_HOME
; break;
212 case GDK_Left
: key_code
= WXK_LEFT
; break;
213 case GDK_Up
: key_code
= WXK_UP
; break;
214 case GDK_Right
: key_code
= WXK_RIGHT
; break;
215 case GDK_Down
: key_code
= WXK_DOWN
; break;
216 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
217 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
218 case GDK_Next
: key_code
= WXK_NEXT
; break;
219 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
220 case GDK_End
: key_code
= WXK_END
; break;
221 case GDK_Begin
: key_code
= WXK_HOME
; break;
222 case GDK_Select
: key_code
= WXK_SELECT
; break;
223 case GDK_Print
: key_code
= WXK_PRINT
; break;
224 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
225 case GDK_Insert
: key_code
= WXK_INSERT
; break;
226 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
227 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
228 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
229 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
230 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
231 case GDK_KP_Up
: key_code
= WXK_UP
; break;
232 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
233 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
234 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
235 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
236 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
237 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
238 case GDK_KP_End
: key_code
= WXK_END
; break;
239 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
240 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
241 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
242 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
243 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
244 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
245 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
246 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
247 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
248 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
249 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
250 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
251 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
252 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
253 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
254 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
255 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
256 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
257 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
258 case GDK_F1
: key_code
= WXK_F1
; break;
259 case GDK_F2
: key_code
= WXK_F2
; break;
260 case GDK_F3
: key_code
= WXK_F3
; break;
261 case GDK_F4
: key_code
= WXK_F4
; break;
262 case GDK_F5
: key_code
= WXK_F5
; break;
263 case GDK_F6
: key_code
= WXK_F6
; break;
264 case GDK_F7
: key_code
= WXK_F7
; break;
265 case GDK_F8
: key_code
= WXK_F8
; break;
266 case GDK_F9
: key_code
= WXK_F9
; break;
267 case GDK_F10
: key_code
= WXK_F10
; break;
268 case GDK_F11
: key_code
= WXK_F11
; break;
269 case GDK_F12
: key_code
= WXK_F12
; break;
272 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
273 key_code
= gdk_event
->keyval
;
277 if (!key_code
) return FALSE
;
279 wxKeyEvent
event( wxEVT_CHAR
);
280 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
281 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
282 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
283 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
284 event
.m_keyCode
= key_code
;
287 event
.SetEventObject( win
);
289 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
293 wxWindow
*ancestor
= win
;
296 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
299 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
300 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
303 ancestor
= ancestor
->GetParent();
309 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
310 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
316 //-----------------------------------------------------------------------------
317 // "button_press_event"
318 //-----------------------------------------------------------------------------
320 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
322 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
324 if (g_blockEventsOnDrag
) return TRUE
;
325 if (g_blockEventsOnScroll
) return TRUE
;
329 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
331 gtk_widget_grab_focus (win
->m_wxwindow
);
334 printf( "GrabFocus from " );
335 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
336 printf( win->GetClassInfo()->GetClassName() );
343 if (!win
->HasVMT()) return TRUE
;
346 printf( "OnButtonPress from " );
347 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
348 printf( win->GetClassInfo()->GetClassName() );
352 wxEventType event_type
= wxEVT_LEFT_DOWN
;
354 if (gdk_event
->button
== 1)
356 switch (gdk_event
->type
)
358 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
359 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
363 else if (gdk_event
->button
== 2)
365 switch (gdk_event
->type
)
367 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
368 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
372 else if (gdk_event
->button
== 3)
374 switch (gdk_event
->type
)
376 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
377 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
382 wxMouseEvent
event( event_type
);
383 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
384 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
385 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
386 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
387 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
388 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
389 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
391 event
.m_x
= (long)gdk_event
->x
;
392 event
.m_y
= (long)gdk_event
->y
;
394 // Some control don't have their own X window and thus cannot get
399 wxNode
*node
= win
->GetChildren().First();
402 wxWindow
*child
= (wxWindow
*)node
->Data();
404 if (child
->m_isStaticBox
)
406 // wxStaticBox is transparent in the box itself
409 int xx1
= child
->m_x
;
410 int yy1
= child
->m_y
;
411 int xx2
= child
->m_x
+ child
->m_width
;
412 int yy2
= child
->m_x
+ child
->m_height
;
415 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
417 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
419 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
421 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
424 event
.m_x
-= child
->m_x
;
425 event
.m_y
-= child
->m_y
;
432 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
433 (child
->m_x
<= event
.m_x
) &&
434 (child
->m_y
<= event
.m_y
) &&
435 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
436 (child
->m_y
+child
->m_height
>= event
.m_y
))
439 event
.m_x
-= child
->m_x
;
440 event
.m_y
-= child
->m_y
;
448 event
.SetEventObject( win
);
450 gs_timeLastClick
= gdk_event
->time
;
452 if (win
->GetEventHandler()->ProcessEvent( event
))
453 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
458 //-----------------------------------------------------------------------------
459 // "button_release_event"
460 //-----------------------------------------------------------------------------
462 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
464 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
466 if (g_blockEventsOnDrag
) return TRUE
;
467 if (g_blockEventsOnScroll
) return TRUE
;
469 if (!win
->HasVMT()) return TRUE
;
472 printf( "OnButtonRelease from " );
473 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
474 printf( win->GetClassInfo()->GetClassName() );
478 wxEventType event_type
= wxEVT_NULL
;
480 switch (gdk_event
->button
)
482 case 1: event_type
= wxEVT_LEFT_UP
; break;
483 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
484 case 3: event_type
= wxEVT_RIGHT_UP
; break;
487 wxMouseEvent
event( event_type
);
488 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
489 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
490 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
491 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
492 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
493 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
494 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
495 event
.m_x
= (long)gdk_event
->x
;
496 event
.m_y
= (long)gdk_event
->y
;
498 // Some control don't have their own X window and thus cannot get
503 wxNode
*node
= win
->GetChildren().First();
506 wxWindow
*child
= (wxWindow
*)node
->Data();
508 if (child
->m_isStaticBox
)
510 // wxStaticBox is transparent in the box itself
513 int xx1
= child
->m_x
;
514 int yy1
= child
->m_y
;
515 int xx2
= child
->m_x
+ child
->m_width
;
516 int yy2
= child
->m_x
+ child
->m_height
;
519 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
521 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
523 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
525 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
528 event
.m_x
-= child
->m_x
;
529 event
.m_y
-= child
->m_y
;
536 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
537 (child
->m_x
<= event
.m_x
) &&
538 (child
->m_y
<= event
.m_y
) &&
539 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
540 (child
->m_y
+child
->m_height
>= event
.m_y
))
543 event
.m_x
-= child
->m_x
;
544 event
.m_y
-= child
->m_y
;
552 event
.SetEventObject( win
);
554 if (win
->GetEventHandler()->ProcessEvent( event
))
555 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
560 //-----------------------------------------------------------------------------
561 // "motion_notify_event"
562 //-----------------------------------------------------------------------------
564 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
566 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
568 if (g_blockEventsOnDrag
) return TRUE
;
569 if (g_blockEventsOnScroll
) return TRUE
;
571 if (!win
->HasVMT()) return TRUE
;
574 printf( "OnMotion from " );
575 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
576 printf( win->GetClassInfo()->GetClassName() );
580 wxMouseEvent
event( wxEVT_MOTION
);
581 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
582 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
583 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
584 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
585 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
586 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
587 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
589 event
.m_x
= (long)gdk_event
->x
;
590 event
.m_y
= (long)gdk_event
->y
;
592 // Some control don't have their own X window and thus cannot get
597 wxNode
*node
= win
->GetChildren().First();
600 wxWindow
*child
= (wxWindow
*)node
->Data();
602 if (child
->m_isStaticBox
)
604 // wxStaticBox is transparent in the box itself
607 int xx1
= child
->m_x
;
608 int yy1
= child
->m_y
;
609 int xx2
= child
->m_x
+ child
->m_width
;
610 int yy2
= child
->m_x
+ child
->m_height
;
613 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
615 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
617 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
619 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
622 event
.m_x
-= child
->m_x
;
623 event
.m_y
-= child
->m_y
;
630 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
631 (child
->m_x
<= event
.m_x
) &&
632 (child
->m_y
<= event
.m_y
) &&
633 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
634 (child
->m_y
+child
->m_height
>= event
.m_y
))
637 event
.m_x
-= child
->m_x
;
638 event
.m_y
-= child
->m_y
;
646 event
.SetEventObject( win
);
648 if (win
->GetEventHandler()->ProcessEvent( event
))
649 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
654 //-----------------------------------------------------------------------------
656 //-----------------------------------------------------------------------------
658 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
660 if (g_blockEventsOnDrag
) return TRUE
;
663 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
665 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
667 printf( "SetFocus flag from " );
668 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
669 printf( win->GetClassInfo()->GetClassName() );
675 if (!win
->HasVMT()) return TRUE
;
678 printf( "OnSetFocus from " );
679 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
680 printf( win->GetClassInfo()->GetClassName() );
682 printf( WXSTRINGCAST win->GetLabel() );
686 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
687 event
.SetEventObject( win
);
689 if (win
->GetEventHandler()->ProcessEvent( event
))
690 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
695 //-----------------------------------------------------------------------------
697 //-----------------------------------------------------------------------------
699 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
701 if (g_blockEventsOnDrag
) return TRUE
;
704 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
705 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
708 if (!win
->HasVMT()) return TRUE
;
711 printf( "OnKillFocus from " );
712 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
713 printf( win->GetClassInfo()->GetClassName() );
717 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
718 event
.SetEventObject( win
);
720 if (win
->GetEventHandler()->ProcessEvent( event
))
721 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
726 //-----------------------------------------------------------------------------
727 // "enter_notify_event"
728 //-----------------------------------------------------------------------------
730 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
732 if (widget
->window
!= gdk_event
->window
) return TRUE
;
734 if (g_blockEventsOnDrag
) return TRUE
;
736 if (!win
->HasVMT()) return TRUE
;
739 printf( "OnEnter from " );
740 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
741 printf( win->GetClassInfo()->GetClassName() );
745 if ((widget
->window
) && (win
->m_cursor
))
746 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
748 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
749 event
.SetEventObject( win
);
753 GdkModifierType state
= (GdkModifierType
)0;
755 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
757 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
758 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
759 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
760 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
761 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
762 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
763 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
768 if (win
->GetEventHandler()->ProcessEvent( event
))
769 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
774 //-----------------------------------------------------------------------------
775 // "leave_notify_event"
776 //-----------------------------------------------------------------------------
778 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
780 if (widget
->window
!= gdk_event
->window
) return TRUE
;
782 if (g_blockEventsOnDrag
) return TRUE
;
784 if (!win
->HasVMT()) return TRUE
;
787 printf( "OnLeave from " );
788 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
789 printf( win->GetClassInfo()->GetClassName() );
793 if ((widget
->window
) && (win
->m_cursor
))
794 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
796 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
797 event
.SetEventObject( win
);
801 GdkModifierType state
= (GdkModifierType
)0;
803 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
805 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
806 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
807 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
808 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
809 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
810 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
811 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
816 if (win
->GetEventHandler()->ProcessEvent( event
))
817 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
822 //-----------------------------------------------------------------------------
823 // "value_changed" from m_vAdjust
824 //-----------------------------------------------------------------------------
826 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
828 if (g_blockEventsOnDrag
) return;
831 printf( "OnVScroll from " );
832 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
833 printf( win->GetClassInfo()->GetClassName() );
837 if (!win
->HasVMT()) return;
839 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
840 if (fabs(diff
) < 0.2) return;
842 wxEventType command
= wxEVT_NULL
;
844 float line_step
= win
->m_vAdjust
->step_increment
;
845 float page_step
= win
->m_vAdjust
->page_increment
;
847 if (win
->m_isScrolling
)
849 command
= wxEVT_SCROLL_THUMBTRACK
;
853 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
854 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
855 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
856 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
857 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
858 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
859 else command
= wxEVT_SCROLL_THUMBTRACK
;
862 int value
= (int)(win
->m_vAdjust
->value
+0.5);
864 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
865 event
.SetEventObject( win
);
866 win
->GetEventHandler()->ProcessEvent( event
);
869 //-----------------------------------------------------------------------------
870 // "value_changed" from m_hAdjust
871 //-----------------------------------------------------------------------------
873 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
875 if (g_blockEventsOnDrag
) return;
878 printf( "OnHScroll from " );
879 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
880 printf( win->GetClassInfo()->GetClassName() );
884 if (!win
->HasVMT()) return;
886 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
887 if (fabs(diff
) < 0.2) return;
889 wxEventType command
= wxEVT_NULL
;
891 float line_step
= win
->m_hAdjust
->step_increment
;
892 float page_step
= win
->m_hAdjust
->page_increment
;
894 if (win
->m_isScrolling
)
896 command
= wxEVT_SCROLL_THUMBTRACK
;
900 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
901 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
902 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
903 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
904 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
905 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
906 else command
= wxEVT_SCROLL_THUMBTRACK
;
909 int value
= (int)(win
->m_hAdjust
->value
+0.5);
911 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
912 event
.SetEventObject( win
);
913 win
->GetEventHandler()->ProcessEvent( event
);
916 //-----------------------------------------------------------------------------
917 // "changed" from m_vAdjust
918 //-----------------------------------------------------------------------------
920 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
922 if (g_blockEventsOnDrag
) return;
925 printf( "OnVScroll change from " );
926 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
927 printf( win->GetClassInfo()->GetClassName() );
931 if (!win
->HasVMT()) return;
933 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
934 int value
= (int)(win
->m_vAdjust
->value
+0.5);
936 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
937 event
.SetEventObject( win
);
938 win
->GetEventHandler()->ProcessEvent( event
);
941 //-----------------------------------------------------------------------------
942 // "changed" from m_hAdjust
943 //-----------------------------------------------------------------------------
945 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
947 if (g_blockEventsOnDrag
) return;
950 printf( "OnHScroll change from " );
951 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
952 printf( win->GetClassInfo()->GetClassName() );
956 if (!win
->HasVMT()) return;
958 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
959 int value
= (int)(win
->m_hAdjust
->value
+0.5);
961 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
962 event
.SetEventObject( win
);
963 win
->GetEventHandler()->ProcessEvent( event
);
966 //-----------------------------------------------------------------------------
967 // "button_press_event" from scrollbar
968 //-----------------------------------------------------------------------------
970 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
971 GdkEventButton
*WXUNUSED(gdk_event
),
974 // don't test here as we can release the mouse while being over
975 // a different window then the slider
977 // if (gdk_event->window != widget->slider) return FALSE;
979 win
->m_isScrolling
= TRUE
;
980 g_blockEventsOnScroll
= TRUE
;
985 //-----------------------------------------------------------------------------
986 // "button_release_event" from scrollbar
987 //-----------------------------------------------------------------------------
989 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
990 GdkEventButton
*WXUNUSED(gdk_event
),
994 // don't test here as we can release the mouse while being over
995 // a different window then the slider
997 // if (gdk_event->window != widget->slider) return FALSE;
999 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1001 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1002 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1004 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1006 win
->m_isScrolling
= FALSE
;
1007 g_blockEventsOnScroll
= FALSE
;
1012 //-----------------------------------------------------------------------------
1013 // InsertChild for wxWindow.
1014 //-----------------------------------------------------------------------------
1016 // Callback for wxWindow. This very strange beast has to be used because
1017 // C++ has no virtual methods in a constructor. We have to emulate a
1018 // virtual function here as wxNotebook requires a different way to insert
1019 // a child in it. I had opted for creating a wxNotebookPage window class
1020 // which would have made this superfluous (such in the MDI window system),
1021 // but no-one was listening to me...
1023 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1025 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1026 GTK_WIDGET(child
->m_widget
),
1030 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1035 //-----------------------------------------------------------------------------
1037 //-----------------------------------------------------------------------------
1039 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1041 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1042 EVT_SIZE(wxWindow::OnSize
)
1043 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1044 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1045 EVT_IDLE(wxWindow::OnIdle
)
1048 wxWindow::wxWindow()
1050 m_widget
= (GtkWidget
*) NULL
;
1051 m_wxwindow
= (GtkWidget
*) NULL
;
1052 m_parent
= (wxWindow
*) NULL
;
1053 m_children
.DeleteContents( FALSE
);
1066 m_eventHandler
= this;
1067 m_windowValidator
= (wxValidator
*) NULL
;
1071 m_cursor
= (wxCursor
*) NULL
;
1072 m_font
= *wxSWISS_FONT
;
1074 m_windowName
= "noname";
1076 m_constraints
= (wxLayoutConstraints
*) NULL
;
1077 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1078 m_windowSizer
= (wxSizer
*) NULL
;
1079 m_sizerParent
= (wxWindow
*) NULL
;
1080 m_autoLayout
= FALSE
;
1084 m_needParent
= TRUE
;
1086 m_hasScrolling
= FALSE
;
1087 m_isScrolling
= FALSE
;
1088 m_hAdjust
= (GtkAdjustment
*) NULL
;
1089 m_vAdjust
= (GtkAdjustment
*) NULL
;
1090 m_oldHorizontalPos
= 0.0;
1091 m_oldVerticalPos
= 0.0;
1096 m_dropTarget
= (wxDropTarget
*) NULL
;
1098 m_scrollGC
= (GdkGC
*) NULL
;
1099 m_widgetStyle
= (GtkStyle
*) NULL
;
1101 m_insertCallback
= wxInsertChildInWindow
;
1103 m_clientObject
= (wxClientData
*) NULL
;
1104 m_clientData
= NULL
;
1106 m_isStaticBox
= FALSE
;
1109 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1110 const wxPoint
&pos
, const wxSize
&size
,
1111 long style
, const wxString
&name
)
1113 m_insertCallback
= wxInsertChildInWindow
;
1114 Create( parent
, id
, pos
, size
, style
, name
);
1117 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1118 const wxPoint
&pos
, const wxSize
&size
,
1119 long style
, const wxString
&name
)
1123 m_needParent
= TRUE
;
1125 PreCreation( parent
, id
, pos
, size
, style
, name
);
1127 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1128 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1130 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1132 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1133 scroll_class
->scrollbar_spacing
= 0;
1135 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1137 m_oldHorizontalPos
= 0.0;
1138 m_oldVerticalPos
= 0.0;
1140 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1141 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1143 m_wxwindow
= gtk_myfixed_new();
1145 #ifdef NEW_GTK_SCROLL_CODE
1146 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1147 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1149 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1150 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1153 if (m_windowStyle
& wxRAISED_BORDER
)
1155 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1157 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1159 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1163 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1166 if (m_windowStyle
& wxTAB_TRAVERSAL
== wxTAB_TRAVERSAL
)
1167 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1169 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1171 // shut the viewport up
1172 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1173 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1175 // I _really_ don't want scrollbars in the beginning
1176 m_vAdjust
->lower
= 0.0;
1177 m_vAdjust
->upper
= 1.0;
1178 m_vAdjust
->value
= 0.0;
1179 m_vAdjust
->step_increment
= 1.0;
1180 m_vAdjust
->page_increment
= 1.0;
1181 m_vAdjust
->page_size
= 5.0;
1182 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1183 m_hAdjust
->lower
= 0.0;
1184 m_hAdjust
->upper
= 1.0;
1185 m_hAdjust
->value
= 0.0;
1186 m_hAdjust
->step_increment
= 1.0;
1187 m_hAdjust
->page_increment
= 1.0;
1188 m_hAdjust
->page_size
= 5.0;
1189 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1191 // these handlers block mouse events to any window during scrolling
1192 // such as motion events and prevent GTK and wxWindows from fighting
1193 // over where the slider should be
1195 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1196 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1198 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1199 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1201 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1202 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1204 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1205 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1207 // these handers het notified when screen updates are required either when
1208 // scrolling or when the window size (and therefore scrollbar configuration)
1211 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1212 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1213 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1214 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1216 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1217 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1218 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1219 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1221 gtk_widget_show( m_wxwindow
);
1223 if (m_parent
) m_parent
->AddChild( this );
1225 (m_parent
->m_insertCallback
)( m_parent
, this );
1234 wxWindow::~wxWindow()
1238 if (m_dropTarget
) delete m_dropTarget
;
1240 if (m_parent
) m_parent
->RemoveChild( this );
1241 if (m_widget
) Show( FALSE
);
1245 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1247 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1249 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1251 if (m_widget
) gtk_widget_destroy( m_widget
);
1253 if (m_cursor
) delete m_cursor
;
1255 DeleteRelatedConstraints();
1258 // This removes any dangling pointers to this window
1259 // in other windows' constraintsInvolvedIn lists.
1260 UnsetConstraints(m_constraints
);
1261 delete m_constraints
;
1262 m_constraints
= (wxLayoutConstraints
*) NULL
;
1266 delete m_windowSizer
;
1267 m_windowSizer
= (wxSizer
*) NULL
;
1269 // If this is a child of a sizer, remove self from parent
1270 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1272 // Just in case the window has been Closed, but
1273 // we're then deleting immediately: don't leave
1274 // dangling pointers.
1275 wxPendingDelete
.DeleteObject(this);
1277 // Just in case we've loaded a top-level window via
1278 // wxWindow::LoadNativeDialog but we weren't a dialog
1280 wxTopLevelWindows
.DeleteObject(this);
1282 if (m_windowValidator
) delete m_windowValidator
;
1284 if (m_clientObject
) delete m_clientObject
;
1287 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1288 const wxPoint
&pos
, const wxSize
&size
,
1289 long style
, const wxString
&name
)
1291 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1293 m_widget
= (GtkWidget
*) NULL
;
1294 m_wxwindow
= (GtkWidget
*) NULL
;
1297 m_children
.DeleteContents( FALSE
);
1300 if (m_width
== -1) m_width
= 20;
1302 if (m_height
== -1) m_height
= 20;
1307 if (!m_needParent
) // some reasonable defaults
1311 m_x
= (gdk_screen_width () - m_width
) / 2;
1312 if (m_x
< 10) m_x
= 10;
1316 m_y
= (gdk_screen_height () - m_height
) / 2;
1317 if (m_y
< 10) m_y
= 10;
1328 m_eventHandler
= this;
1330 m_windowId
= id
== -1 ? wxNewId() : id
;
1334 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1335 m_font
= *wxSWISS_FONT
;
1336 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1337 m_foregroundColour
= *wxBLACK
;
1338 m_windowStyle
= style
;
1339 m_windowName
= name
;
1341 m_constraints
= (wxLayoutConstraints
*) NULL
;
1342 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1343 m_windowSizer
= (wxSizer
*) NULL
;
1344 m_sizerParent
= (wxWindow
*) NULL
;
1345 m_autoLayout
= FALSE
;
1347 m_hasScrolling
= FALSE
;
1348 m_isScrolling
= FALSE
;
1349 m_hAdjust
= (GtkAdjustment
*) NULL
;
1350 m_vAdjust
= (GtkAdjustment
*) NULL
;
1351 m_oldHorizontalPos
= 0.0;
1352 m_oldVerticalPos
= 0.0;
1357 m_dropTarget
= (wxDropTarget
*) NULL
;
1359 m_windowValidator
= (wxValidator
*) NULL
;
1360 m_scrollGC
= (GdkGC
*) NULL
;
1361 m_widgetStyle
= (GtkStyle
*) NULL
;
1363 m_clientObject
= (wxClientData
*)NULL
;
1364 m_clientData
= NULL
;
1366 m_isStaticBox
= FALSE
;
1369 void wxWindow::PostCreation()
1373 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1374 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1376 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1377 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1380 ConnectWidget( GetConnectWidget() );
1382 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1384 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1386 SetCursor( *wxSTANDARD_CURSOR
);
1391 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1393 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1394 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1396 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1397 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1399 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1400 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1402 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1403 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1405 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1406 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1408 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1409 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1411 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1412 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1414 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1415 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1418 bool wxWindow::HasVMT()
1423 bool wxWindow::Close( bool force
)
1425 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1427 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1428 event
.SetEventObject(this);
1429 event
.SetForce(force
);
1431 return GetEventHandler()->ProcessEvent(event
);
1434 bool wxWindow::Destroy()
1436 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1443 bool wxWindow::DestroyChildren()
1446 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1449 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1452 if (m_children
.Member(child
)) delete node
;
1458 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1460 // are we to set fonts here ?
1463 wxPoint
wxWindow::GetClientAreaOrigin() const
1465 return wxPoint(0,0);
1468 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1470 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1472 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1478 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1480 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1481 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1483 if (m_resizing
) return; // I don't like recursions
1486 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1488 // don't set the size for children of wxNotebook, just take the values.
1496 int old_width
= m_width
;
1497 int old_height
= m_height
;
1499 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1501 if (x
!= -1) m_x
= x
;
1502 if (y
!= -1) m_y
= y
;
1503 if (width
!= -1) m_width
= width
;
1504 if (height
!= -1) m_height
= height
;
1514 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1516 if (width
== -1) m_width
= 80;
1519 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1521 if (height
== -1) m_height
= 26;
1524 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1525 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1526 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_minWidth
;
1527 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_minHeight
;
1529 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1530 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1532 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1533 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1538 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1539 event
.SetEventObject( this );
1540 GetEventHandler()->ProcessEvent( event
);
1545 void wxWindow::SetSize( int width
, int height
)
1547 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1550 void wxWindow::Move( int x
, int y
)
1552 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1555 void wxWindow::GetSize( int *width
, int *height
) const
1557 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1559 if (width
) (*width
) = m_width
;
1560 if (height
) (*height
) = m_height
;
1563 void wxWindow::SetClientSize( int width
, int height
)
1565 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1569 SetSize( width
, height
);
1576 if (!m_hasScrolling
)
1578 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1580 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1581 (m_windowStyle
& wxSUNKEN_BORDER
))
1583 dw
+= 2 * window_class
->xthickness
;
1584 dh
+= 2 * window_class
->ythickness
;
1589 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1590 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1592 #ifdef NEW_GTK_SCROLL_CODE
1593 GtkWidget
*viewport
= scroll_window
->child
;
1595 GtkWidget
*viewport
= scroll_window
->viewport
;
1598 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1600 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1601 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1603 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1604 (m_windowStyle
& wxSUNKEN_BORDER
))
1606 dw
+= 2 * viewport_class
->xthickness
;
1607 dh
+= 2 * viewport_class
->ythickness
;
1610 if (scroll_window
->vscrollbar_visible
)
1612 dw
+= vscrollbar
->allocation
.width
;
1613 dw
+= scroll_class
->scrollbar_spacing
;
1616 if (scroll_window
->hscrollbar_visible
)
1618 dh
+= hscrollbar
->allocation
.height
;
1619 dw
+= scroll_class
->scrollbar_spacing
;
1623 SetSize( width
+dw
, height
+dh
);
1627 void wxWindow::GetClientSize( int *width
, int *height
) const
1629 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1633 if (width
) (*width
) = m_width
;
1634 if (height
) (*height
) = m_height
;
1641 if (!m_hasScrolling
)
1643 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1645 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1646 (m_windowStyle
& wxSUNKEN_BORDER
))
1648 dw
+= 2 * window_class
->xthickness
;
1649 dh
+= 2 * window_class
->ythickness
;
1654 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1655 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1657 #ifdef NEW_GTK_SCROLL_CODE
1658 GtkWidget
*viewport
= scroll_window
->child
;
1660 GtkWidget
*viewport
= scroll_window
->viewport
;
1663 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1665 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1666 (m_windowStyle
& wxSUNKEN_BORDER
))
1668 dw
+= 2 * viewport_class
->xthickness
;
1669 dh
+= 2 * viewport_class
->ythickness
;
1672 if (scroll_window
->vscrollbar_visible
)
1674 // dw += vscrollbar->allocation.width;
1675 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1676 dw
+= scroll_class
->scrollbar_spacing
;
1679 if (scroll_window
->hscrollbar_visible
)
1681 // dh += hscrollbar->allocation.height;
1683 dh
+= scroll_class
->scrollbar_spacing
;
1687 if (width
) (*width
) = m_width
- dw
;
1688 if (height
) (*height
) = m_height
- dh
;
1692 void wxWindow::GetPosition( int *x
, int *y
) const
1694 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1700 void wxWindow::ClientToScreen( int *x
, int *y
)
1702 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1704 GdkWindow
*source
= (GdkWindow
*) NULL
;
1706 source
= m_wxwindow
->window
;
1708 source
= m_widget
->window
;
1712 gdk_window_get_origin( source
, &org_x
, &org_y
);
1716 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1718 org_x
+= m_widget
->allocation
.x
;
1719 org_y
+= m_widget
->allocation
.y
;
1723 wxPoint
pt(GetClientAreaOrigin());
1731 void wxWindow::ScreenToClient( int *x
, int *y
)
1733 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1735 GdkWindow
*source
= (GdkWindow
*) NULL
;
1737 source
= m_wxwindow
->window
;
1739 source
= m_widget
->window
;
1743 gdk_window_get_origin( source
, &org_x
, &org_y
);
1747 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1749 org_x
+= m_widget
->allocation
.x
;
1750 org_y
+= m_widget
->allocation
.y
;
1754 wxPoint
pt(GetClientAreaOrigin());
1762 void wxWindow::Centre( int direction
)
1764 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1773 m_parent
->GetSize( &p_w
, &p_h
);
1774 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
1775 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
1779 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
1780 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
1786 void wxWindow::Fit()
1788 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1792 wxNode
*node
= m_children
.First();
1795 wxWindow
*win
= (wxWindow
*)node
->Data();
1797 win
->GetPosition(&wx
, &wy
);
1798 win
->GetSize(&ww
, &wh
);
1799 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
1800 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
1802 node
= node
->Next();
1805 SetClientSize(maxX
+ 7, maxY
+ 14);
1808 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1810 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1818 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1820 // if (GetAutoLayout()) Layout();
1823 bool wxWindow::Show( bool show
)
1825 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
1828 gtk_widget_show( m_widget
);
1830 gtk_widget_hide( m_widget
);
1837 void wxWindow::Enable( bool enable
)
1839 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1841 m_isEnabled
= enable
;
1843 gtk_widget_set_sensitive( m_widget
, enable
);
1844 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1847 int wxWindow::GetCharHeight() const
1849 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
1851 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
1853 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1855 return font
->ascent
+ font
->descent
;
1858 int wxWindow::GetCharWidth() const
1860 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
1862 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
1864 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1866 return gdk_string_width( font
, "H" );
1869 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1870 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1872 wxFont fontToUse
= m_font
;
1873 if (theFont
) fontToUse
= *theFont
;
1875 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
1877 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1878 if (x
) (*x
) = gdk_string_width( font
, string
);
1879 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1880 if (descent
) (*descent
) = font
->descent
;
1881 if (externalLeading
) (*externalLeading
) = 0; // ??
1884 void wxWindow::MakeModal( bool modal
)
1888 // Disable all other windows
1889 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1891 wxNode
*node
= wxTopLevelWindows
.First();
1894 wxWindow
*win
= (wxWindow
*)node
->Data();
1895 if (win
!= this) win
->Enable(!modal
);
1897 node
= node
->Next();
1902 void wxWindow::SetFocus()
1904 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1906 GtkWidget
*connect_widget
= GetConnectWidget();
1909 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) && !GTK_WIDGET_HAS_FOCUS (connect_widget
) )
1911 gtk_widget_grab_focus (connect_widget
);
1916 bool wxWindow::OnClose()
1921 void wxWindow::AddChild( wxWindow
*child
)
1923 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1924 wxCHECK_RET( (child
!= NULL
), "invalid child" );
1926 m_children
.Append( child
);
1929 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
1931 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
1933 wxWindow
*oldParent
= GetParent();
1935 if (oldParent
) oldParent
->RemoveChild( this );
1937 gtk_widget_unparent( m_widget
);
1941 newParent
->AddChild( this );
1942 (newParent
->m_insertCallback
)( newParent
, this );
1948 void wxWindow::RemoveChild( wxWindow
*child
)
1950 m_children
.DeleteObject( child
);
1951 child
->m_parent
= (wxWindow
*) NULL
;
1954 void wxWindow::SetReturnCode( int retCode
)
1956 m_retCode
= retCode
;
1959 int wxWindow::GetReturnCode()
1964 void wxWindow::Raise()
1966 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1968 if (m_widget
) gdk_window_raise( m_widget
->window
);
1971 void wxWindow::Lower()
1973 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1975 if (m_widget
) gdk_window_lower( m_widget
->window
);
1978 wxEvtHandler
*wxWindow::GetEventHandler() const
1980 return m_eventHandler
;
1983 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
1985 m_eventHandler
= handler
;
1988 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
1990 handler
->SetNextHandler(GetEventHandler());
1991 SetEventHandler(handler
);
1994 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
1996 if (GetEventHandler())
1998 wxEvtHandler
*handlerA
= GetEventHandler();
1999 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2000 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2001 SetEventHandler(handlerB
);
2005 return (wxEvtHandler
*) NULL
;
2011 return (wxEvtHandler
*) NULL
;
2014 wxValidator
*wxWindow::GetValidator()
2016 return m_windowValidator
;
2019 void wxWindow::SetValidator( const wxValidator
& validator
)
2021 if (m_windowValidator
) delete m_windowValidator
;
2022 m_windowValidator
= validator
.Clone();
2023 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2026 void wxWindow::SetClientObject( wxClientData
*data
)
2028 if (m_clientObject
) delete m_clientObject
;
2029 m_clientObject
= data
;
2032 wxClientData
*wxWindow::GetClientObject()
2034 return m_clientObject
;
2037 void wxWindow::SetClientData( void *data
)
2039 m_clientData
= data
;
2042 void *wxWindow::GetClientData()
2044 return m_clientData
;
2047 bool wxWindow::IsBeingDeleted()
2052 void wxWindow::SetId( wxWindowID id
)
2057 wxWindowID
wxWindow::GetId() const
2062 void wxWindow::SetCursor( const wxCursor
&cursor
)
2064 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2068 if (cursor
== *m_cursor
) return;
2073 *m_cursor
= *wxSTANDARD_CURSOR
;
2076 if ((m_widget
) && (m_widget
->window
))
2077 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2079 if ((m_wxwindow
) && (m_wxwindow
->window
))
2080 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2083 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2085 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2087 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2091 gdk_window_clear_area( m_wxwindow
->window
,
2105 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2107 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2111 GdkRectangle gdk_rect
;
2112 gdk_rect
.x
= rect
->x
;
2113 gdk_rect
.y
= rect
->y
;
2114 gdk_rect
.width
= rect
->width
;
2115 gdk_rect
.height
= rect
->height
;
2118 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2120 gtk_widget_draw( m_widget
, &gdk_rect
);
2124 wxRegion
wxWindow::GetUpdateRegion() const
2126 return m_updateRegion
;
2129 bool wxWindow::IsExposed( int x
, int y
) const
2131 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2134 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2136 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2139 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2141 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2144 bool wxWindow::IsExposed( const wxRect
& rect
) const
2146 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2149 void wxWindow::Clear()
2151 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2153 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2156 wxColour
wxWindow::GetBackgroundColour() const
2158 return m_backgroundColour
;
2161 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2163 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2165 if (m_backgroundColour
== colour
) return;
2167 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2168 if (sysbg
.Red() == colour
.Red() &&
2169 sysbg
.Green() == colour
.Green() &&
2170 sysbg
.Blue() == colour
.Blue())
2175 m_backgroundColour
= colour
;
2176 if (!m_backgroundColour
.Ok()) return;
2180 GdkWindow
*window
= m_wxwindow
->window
;
2181 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2182 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2183 gdk_window_clear( window
);
2189 wxColour
wxWindow::GetForegroundColour() const
2191 return m_foregroundColour
;
2194 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2196 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2198 if (m_foregroundColour
== colour
) return;
2200 m_foregroundColour
= colour
;
2201 if (!m_foregroundColour
.Ok()) return;
2206 GtkStyle
*wxWindow::GetWidgetStyle()
2208 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2212 gtk_widget_get_style( m_widget
) );
2214 return m_widgetStyle
;
2217 void wxWindow::SetWidgetStyle()
2219 GtkStyle
*style
= GetWidgetStyle();
2221 gdk_font_unref( style
->font
);
2222 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2224 if (m_foregroundColour
.Ok())
2226 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2227 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2228 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2229 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2232 if (m_backgroundColour
.Ok())
2234 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2235 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2236 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2237 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2238 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2239 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2240 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2241 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2242 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2246 void wxWindow::ApplyWidgetStyle()
2250 bool wxWindow::Validate()
2252 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2254 wxNode
*node
= m_children
.First();
2257 wxWindow
*child
= (wxWindow
*)node
->Data();
2258 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2262 node
= node
->Next();
2267 bool wxWindow::TransferDataToWindow()
2269 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2271 wxNode
*node
= m_children
.First();
2274 wxWindow
*child
= (wxWindow
*)node
->Data();
2275 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2276 !child
->GetValidator()->TransferToWindow() )
2278 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2281 node
= node
->Next();
2286 bool wxWindow::TransferDataFromWindow()
2288 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2290 wxNode
*node
= m_children
.First();
2293 wxWindow
*child
= (wxWindow
*)node
->Data();
2294 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2298 node
= node
->Next();
2303 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2305 m_acceleratorTable
= accel
;
2308 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2310 TransferDataToWindow();
2313 void wxWindow::InitDialog()
2315 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2317 wxInitDialogEvent
event(GetId());
2318 event
.SetEventObject( this );
2319 GetEventHandler()->ProcessEvent(event
);
2322 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2324 menu
->SetInvokingWindow( win
);
2325 wxNode
*node
= menu
->m_items
.First();
2328 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2329 if (menuitem
->IsSubMenu())
2331 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2333 node
= node
->Next();
2337 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2339 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2341 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2343 SetInvokingWindow( menu
, this );
2345 GTK_MENU(menu
->m_menu
),
2346 (GtkWidget
*)NULL
, // parent menu shell
2347 (GtkWidget
*)NULL
, // parent menu item
2348 (GtkMenuPositionFunc
)NULL
,
2349 NULL
, // client data
2350 0, // button used to activate it
2351 0//gs_timeLastClick // the time of activation
2356 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2358 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2360 GtkWidget
*dnd_widget
= GetConnectWidget();
2362 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2364 if (m_dropTarget
) delete m_dropTarget
;
2365 m_dropTarget
= dropTarget
;
2367 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2370 wxDropTarget
*wxWindow::GetDropTarget() const
2372 return m_dropTarget
;
2375 GtkWidget
* wxWindow::GetConnectWidget()
2377 GtkWidget
*connect_widget
= m_widget
;
2378 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2380 return connect_widget
;
2383 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2385 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2386 return (window
== m_widget
->window
);
2389 void wxWindow::SetFont( const wxFont
&font
)
2391 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2393 if (((wxFont
*)&font
)->Ok())
2396 m_font
= *wxSWISS_FONT
;
2401 void wxWindow::SetWindowStyleFlag( long flag
)
2403 m_windowStyle
= flag
;
2406 long wxWindow::GetWindowStyleFlag() const
2408 return m_windowStyle
;
2411 void wxWindow::CaptureMouse()
2413 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2415 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2417 GtkWidget
*connect_widget
= GetConnectWidget();
2418 gtk_grab_add( connect_widget
);
2419 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2421 (GDK_BUTTON_PRESS_MASK
|
2422 GDK_BUTTON_RELEASE_MASK
|
2423 GDK_POINTER_MOTION_MASK
),
2430 void wxWindow::ReleaseMouse()
2432 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2434 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2436 GtkWidget
*connect_widget
= GetConnectWidget();
2437 gtk_grab_remove( connect_widget
);
2438 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2439 g_capturing
= FALSE
;
2442 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2446 wxString
wxWindow::GetTitle() const
2448 return (wxString
&)m_windowName
;
2451 wxString
wxWindow::GetLabel() const
2456 void wxWindow::SetName( const wxString
&name
)
2458 m_windowName
= name
;
2461 wxString
wxWindow::GetName() const
2463 return (wxString
&)m_windowName
;
2466 bool wxWindow::IsShown() const
2471 bool wxWindow::IsRetained()
2476 wxWindow
*wxWindow::FindWindow( long id
)
2478 if (id
== m_windowId
) return this;
2479 wxNode
*node
= m_children
.First();
2482 wxWindow
*child
= (wxWindow
*)node
->Data();
2483 wxWindow
*res
= child
->FindWindow( id
);
2484 if (res
) return res
;
2485 node
= node
->Next();
2487 return (wxWindow
*) NULL
;
2490 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2492 if (name
== m_windowName
) return this;
2493 wxNode
*node
= m_children
.First();
2496 wxWindow
*child
= (wxWindow
*)node
->Data();
2497 wxWindow
*res
= child
->FindWindow( name
);
2498 if (res
) return res
;
2499 node
= node
->Next();
2501 return (wxWindow
*) NULL
;
2504 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2505 int range
, bool refresh
)
2507 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2509 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2511 m_hasScrolling
= TRUE
;
2513 if (orient
== wxHORIZONTAL
)
2515 float fpos
= (float)pos
;
2516 float frange
= (float)range
;
2517 float fthumb
= (float)thumbVisible
;
2518 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2519 if (fpos
< 0.0) fpos
= 0.0;
2521 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2522 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2524 SetScrollPos( orient
, pos
, refresh
);
2528 m_oldHorizontalPos
= fpos
;
2530 m_hAdjust
->lower
= 0.0;
2531 m_hAdjust
->upper
= frange
;
2532 m_hAdjust
->value
= fpos
;
2533 m_hAdjust
->step_increment
= 1.0;
2534 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2535 m_hAdjust
->page_size
= fthumb
;
2539 float fpos
= (float)pos
;
2540 float frange
= (float)range
;
2541 float fthumb
= (float)thumbVisible
;
2542 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2543 if (fpos
< 0.0) fpos
= 0.0;
2545 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2546 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2548 SetScrollPos( orient
, pos
, refresh
);
2552 m_oldVerticalPos
= fpos
;
2554 m_vAdjust
->lower
= 0.0;
2555 m_vAdjust
->upper
= frange
;
2556 m_vAdjust
->value
= fpos
;
2557 m_vAdjust
->step_increment
= 1.0;
2558 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2559 m_vAdjust
->page_size
= fthumb
;
2562 if (m_wxwindow
->window
)
2564 if (orient
== wxHORIZONTAL
)
2565 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2567 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2569 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2573 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2575 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2577 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2579 if (orient
== wxHORIZONTAL
)
2581 float fpos
= (float)pos
;
2582 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2583 if (fpos
< 0.0) fpos
= 0.0;
2584 m_oldHorizontalPos
= fpos
;
2586 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2587 m_hAdjust
->value
= fpos
;
2591 float fpos
= (float)pos
;
2592 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2593 if (fpos
< 0.0) fpos
= 0.0;
2594 m_oldVerticalPos
= fpos
;
2596 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2597 m_vAdjust
->value
= fpos
;
2602 if (m_wxwindow
->window
)
2604 if (orient
== wxHORIZONTAL
)
2605 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2607 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2612 int wxWindow::GetScrollThumb( int orient
) const
2614 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2616 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2618 if (orient
== wxHORIZONTAL
)
2619 return (int)(m_hAdjust
->page_size
+0.5);
2621 return (int)(m_vAdjust
->page_size
+0.5);
2624 int wxWindow::GetScrollPos( int orient
) const
2626 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2628 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2630 if (orient
== wxHORIZONTAL
)
2631 return (int)(m_hAdjust
->value
+0.5);
2633 return (int)(m_vAdjust
->value
+0.5);
2636 int wxWindow::GetScrollRange( int orient
) const
2638 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2640 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2642 if (orient
== wxHORIZONTAL
)
2643 return (int)(m_hAdjust
->upper
+0.5);
2645 return (int)(m_vAdjust
->upper
+0.5);
2648 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2650 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2652 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2656 GetClientSize( &cw
, &ch
);
2658 int w
= cw
- abs(dx
);
2659 int h
= ch
- abs(dy
);
2660 if ((h
< 0) || (w
< 0))
2667 if (dx
< 0) s_x
= -dx
;
2668 if (dy
< 0) s_y
= -dy
;
2671 if (dx
> 0) d_x
= dx
;
2672 if (dy
> 0) d_y
= dy
;
2676 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2677 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2680 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2681 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2684 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2685 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2686 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2687 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2689 Refresh( TRUE
, &rect
);
2692 //-------------------------------------------------------------------------------------
2694 //-------------------------------------------------------------------------------------
2696 wxLayoutConstraints
*wxWindow::GetConstraints() const
2698 return m_constraints
;
2701 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2705 UnsetConstraints(m_constraints
);
2706 delete m_constraints
;
2708 m_constraints
= constraints
;
2711 // Make sure other windows know they're part of a 'meaningful relationship'
2712 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2713 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2714 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2715 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2716 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2717 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2718 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2719 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2720 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2721 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2722 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2723 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2724 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2725 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2726 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2727 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2733 void wxWindow::SetAutoLayout( bool autoLayout
)
2735 m_autoLayout
= autoLayout
;
2738 bool wxWindow::GetAutoLayout() const
2740 return m_autoLayout
;
2743 wxSizer
*wxWindow::GetSizer() const
2745 return m_windowSizer
;
2748 void wxWindow::SetSizerParent( wxWindow
*win
)
2750 m_sizerParent
= win
;
2753 wxWindow
*wxWindow::GetSizerParent() const
2755 return m_sizerParent
;
2758 // This removes any dangling pointers to this window
2759 // in other windows' constraintsInvolvedIn lists.
2760 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2764 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2765 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2766 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2767 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2768 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2769 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2770 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2771 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2772 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2773 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2774 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2775 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2776 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2777 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2778 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2779 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2783 // Back-pointer to other windows we're involved with, so if we delete
2784 // this window, we must delete any constraints we're involved with.
2785 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2787 if (!m_constraintsInvolvedIn
)
2788 m_constraintsInvolvedIn
= new wxList
;
2789 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2790 m_constraintsInvolvedIn
->Append(otherWin
);
2793 // REMOVE back-pointer to other windows we're involved with.
2794 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2796 if (m_constraintsInvolvedIn
)
2797 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2800 // Reset any constraints that mention this window
2801 void wxWindow::DeleteRelatedConstraints()
2803 if (m_constraintsInvolvedIn
)
2805 wxNode
*node
= m_constraintsInvolvedIn
->First();
2808 wxWindow
*win
= (wxWindow
*)node
->Data();
2809 wxNode
*next
= node
->Next();
2810 wxLayoutConstraints
*constr
= win
->GetConstraints();
2812 // Reset any constraints involving this window
2815 constr
->left
.ResetIfWin((wxWindow
*)this);
2816 constr
->top
.ResetIfWin((wxWindow
*)this);
2817 constr
->right
.ResetIfWin((wxWindow
*)this);
2818 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2819 constr
->width
.ResetIfWin((wxWindow
*)this);
2820 constr
->height
.ResetIfWin((wxWindow
*)this);
2821 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2822 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2827 delete m_constraintsInvolvedIn
;
2828 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2832 void wxWindow::SetSizer(wxSizer
*sizer
)
2834 m_windowSizer
= sizer
;
2836 sizer
->SetSizerParent((wxWindow
*)this);
2843 bool wxWindow::Layout()
2845 if (GetConstraints())
2848 GetClientSize(&w
, &h
);
2849 GetConstraints()->width
.SetValue(w
);
2850 GetConstraints()->height
.SetValue(h
);
2853 // If top level (one sizer), evaluate the sizer's constraints.
2857 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2858 GetSizer()->LayoutPhase1(&noChanges
);
2859 GetSizer()->LayoutPhase2(&noChanges
);
2860 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2865 // Otherwise, evaluate child constraints
2866 ResetConstraints(); // Mark all constraints as unevaluated
2867 DoPhase(1); // Just one phase need if no sizers involved
2869 SetConstraintSizes(); // Recursively set the real window sizes
2875 // Do a phase of evaluating constraints:
2876 // the default behaviour. wxSizers may do a similar
2877 // thing, but also impose their own 'constraints'
2878 // and order the evaluation differently.
2879 bool wxWindow::LayoutPhase1(int *noChanges
)
2881 wxLayoutConstraints
*constr
= GetConstraints();
2884 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
2890 bool wxWindow::LayoutPhase2(int *noChanges
)
2900 // Do a phase of evaluating child constraints
2901 bool wxWindow::DoPhase(int phase
)
2903 int noIterations
= 0;
2904 int maxIterations
= 500;
2908 while ((noChanges
> 0) && (noIterations
< maxIterations
))
2912 wxNode
*node
= m_children
.First();
2915 wxWindow
*child
= (wxWindow
*)node
->Data();
2916 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
2918 wxLayoutConstraints
*constr
= child
->GetConstraints();
2921 if (succeeded
.Member(child
))
2926 int tempNoChanges
= 0;
2927 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
2928 noChanges
+= tempNoChanges
;
2931 succeeded
.Append(child
);
2936 node
= node
->Next();
2943 void wxWindow::ResetConstraints()
2945 wxLayoutConstraints
*constr
= GetConstraints();
2948 constr
->left
.SetDone(FALSE
);
2949 constr
->top
.SetDone(FALSE
);
2950 constr
->right
.SetDone(FALSE
);
2951 constr
->bottom
.SetDone(FALSE
);
2952 constr
->width
.SetDone(FALSE
);
2953 constr
->height
.SetDone(FALSE
);
2954 constr
->centreX
.SetDone(FALSE
);
2955 constr
->centreY
.SetDone(FALSE
);
2957 wxNode
*node
= m_children
.First();
2960 wxWindow
*win
= (wxWindow
*)node
->Data();
2961 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2962 win
->ResetConstraints();
2963 node
= node
->Next();
2967 // Need to distinguish between setting the 'fake' size for
2968 // windows and sizers, and setting the real values.
2969 void wxWindow::SetConstraintSizes(bool recurse
)
2971 wxLayoutConstraints
*constr
= GetConstraints();
2972 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
2973 constr
->width
.GetDone() && constr
->height
.GetDone())
2975 int x
= constr
->left
.GetValue();
2976 int y
= constr
->top
.GetValue();
2977 int w
= constr
->width
.GetValue();
2978 int h
= constr
->height
.GetValue();
2980 // If we don't want to resize this window, just move it...
2981 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
2982 (constr
->height
.GetRelationship() != wxAsIs
))
2984 // Calls Layout() recursively. AAAGH. How can we stop that.
2985 // Simply take Layout() out of non-top level OnSizes.
2986 SizerSetSize(x
, y
, w
, h
);
2995 char *windowClass
= this->GetClassInfo()->GetClassName();
2998 if (GetName() == "")
2999 winName
= "unnamed";
3001 winName
= GetName();
3002 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3003 (const char *)windowClass
,
3004 (const char *)winName
);
3005 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3006 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3007 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3008 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3009 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3014 wxNode
*node
= m_children
.First();
3017 wxWindow
*win
= (wxWindow
*)node
->Data();
3018 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3019 win
->SetConstraintSizes();
3020 node
= node
->Next();
3025 // This assumes that all sizers are 'on' the same
3026 // window, i.e. the parent of this window.
3027 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3029 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3030 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3034 m_sizerParent
->GetPosition(&xp
, &yp
);
3035 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3040 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3044 TransformSizerToActual(&xx
, &yy
);
3045 SetSize(xx
, yy
, w
, h
);
3048 void wxWindow::SizerMove(int x
, int y
)
3052 TransformSizerToActual(&xx
, &yy
);
3056 // Only set the size/position of the constraint (if any)
3057 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3059 wxLayoutConstraints
*constr
= GetConstraints();
3064 constr
->left
.SetValue(x
);
3065 constr
->left
.SetDone(TRUE
);
3069 constr
->top
.SetValue(y
);
3070 constr
->top
.SetDone(TRUE
);
3074 constr
->width
.SetValue(w
);
3075 constr
->width
.SetDone(TRUE
);
3079 constr
->height
.SetValue(h
);
3080 constr
->height
.SetDone(TRUE
);
3085 void wxWindow::MoveConstraint(int x
, int y
)
3087 wxLayoutConstraints
*constr
= GetConstraints();
3092 constr
->left
.SetValue(x
);
3093 constr
->left
.SetDone(TRUE
);
3097 constr
->top
.SetValue(y
);
3098 constr
->top
.SetDone(TRUE
);
3103 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3105 wxLayoutConstraints
*constr
= GetConstraints();
3108 *w
= constr
->width
.GetValue();
3109 *h
= constr
->height
.GetValue();
3115 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3117 wxLayoutConstraints
*constr
= GetConstraints();
3120 *w
= constr
->width
.GetValue();
3121 *h
= constr
->height
.GetValue();
3124 GetClientSize(w
, h
);
3127 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3129 wxLayoutConstraints
*constr
= GetConstraints();
3132 *x
= constr
->left
.GetValue();
3133 *y
= constr
->top
.GetValue();
3139 bool wxWindow::AcceptsFocus() const
3141 return IsEnabled() && IsShown();
3144 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )