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"
28 #include "wx/notebook.h"
29 #include "wx/statusbr.h"
31 #include "wx/gtk/win_gtk.h"
32 #include "gdk/gdkprivate.h"
33 #include "gdk/gdkkeysyms.h"
37 //-----------------------------------------------------------------------------
38 // documentation on internals
39 //-----------------------------------------------------------------------------
42 I have been asked several times about writing some documentation about
43 the GTK port of wxWindows, especially its internal structures. Obviously,
44 you cannot understand wxGTK without knowing a little about the GTK, but
45 some more information about what the wxWindow, which is the base class
46 for all other window classes, does seems required as well.
48 What does wxWindow do? It contains the common interface for the following
49 jobs of its descentants:
51 1) Define the rudimentary behaviour common to all window classes, such as
52 resizing, intercepting user input so as to make it possible to use these
53 events for special purposes in a derived class, window names etc.
55 2) Provide the possibility to contain and manage children, if the derived
56 class is allowed to contain children, which holds true for those window
57 classes, which do not display a native GTK widget. To name them, these
58 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
59 work classes are a special case and are handled a bit differently from
62 3) Provide the possibility to draw into a client area of a window. This,
63 too, only holds true for classes that do not display a native GTK widget
66 4) Provide the entire mechanism for scrolling widgets. This actaul inter-
67 face for this is usually in wxScrolledWidget, but the GTK implementation
70 5) A multitude of helper or extra methods for special purposes, such as
71 Drag'n'Drop, managing validators etc.
73 Normally one might expect, that one wxWindows class would always contain
74 one GTK widget. Under GTK, there is no such allround widget that has all
75 the functionality. Moreover, the GTK defines a client area as a different
76 widget from the actual widget you are handling. Last but not least some
77 special classes (e.g. wxFrame) handle different categories of widgets and
78 still have the possibility to draw something in the client area.
79 It was therefore required to write a special purpose GTK widget, that would
80 represent a client area in the sense of wxWindows capable to do the jobs
81 2), 3) and 4). I have written this class and it resides in win_gtk.c of
84 All windows must have a widget, with which they interact with other under-
85 lying GTK widget. It is this widget, e.g. that has to be resized etc and
86 thw wxWindow class has a member variable called m_widget which holds a
87 pointer to this widget. When the window class displays a GTK native widget,
88 this is the only GTK widget the class manages. When the class has a client
89 area for drawing into and for containing children it must have at least
90 one more GTK widget to handle (of the type GtkMyFixed, defined in win_gtk.c),
91 but there can be any number of widgets, handled by a class (e.g. the frame
92 class handles three). The common rule for all windows is only, that the
93 widget that interacts with the rest of GTK must be referenced in m_widget
94 and all other widgets must be children of this widget on the GTK level.
95 The top-most widget, which also represents the client area, must be in
96 the m_wxwindow field and must be of the type GtkMyFixed.
98 As I said, the window classes that display a GTK native widget only have
99 one widget, so in the case of e.g. the wxButton class m_widget holds a
100 pointer to a GtkButton widget. But windows with client areas (for drawing
101 and children) have a m_widget field that is a pointer to a GtkScrolled-
102 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
103 one is (in the GTK sense) a child of the GtkScrolledWindow.
105 If the m_wxwindow field is set, then all input to this widget is inter-
106 cepted and sent to the wxWindows class. If not, all input to the widget
107 that gets pointed to by m_widget gets intercepted and sent to the class.
111 //-----------------------------------------------------------------------------
113 //-----------------------------------------------------------------------------
115 extern wxList wxPendingDelete
;
116 extern wxList wxTopLevelWindows
;
117 extern bool g_blockEventsOnDrag
;
118 static bool g_capturing
= FALSE
;
120 // hack: we need something to pass to gtk_menu_popup, so we store the time of
121 // the last click here
122 static guint32 gs_timeLastClick
= 0;
124 //-----------------------------------------------------------------------------
125 // "expose_event" (of m_wxwindow, not of m_widget)
126 //-----------------------------------------------------------------------------
128 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
130 if (!win
->HasVMT()) return;
131 if (g_blockEventsOnDrag
) return;
133 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
135 gdk_event
->area
.width
,
136 gdk_event
->area
.height
);
138 if (gdk_event
->count
> 0) return;
141 printf( "OnExpose from " );
142 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
143 printf( win->GetClassInfo()->GetClassName() );
147 wxPaintEvent
event( win
->GetId() );
148 event
.SetEventObject( win
);
149 win
->GetEventHandler()->ProcessEvent( event
);
151 win
->m_updateRegion
.Clear();
154 //-----------------------------------------------------------------------------
155 // "draw" (of m_wxwindow, not of m_widget)
156 //-----------------------------------------------------------------------------
158 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
160 if (!win
->HasVMT()) return;
161 if (g_blockEventsOnDrag
) return;
163 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
165 wxPaintEvent
event( win
->GetId() );
166 event
.SetEventObject( win
);
167 win
->GetEventHandler()->ProcessEvent( event
);
169 win
->m_updateRegion
.Clear();
172 //-----------------------------------------------------------------------------
174 //-----------------------------------------------------------------------------
176 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
178 if (!win
->HasVMT()) return FALSE
;
179 if (g_blockEventsOnDrag
) return FALSE
;
182 printf( "OnKeyPress from " );
183 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
184 printf( win->GetClassInfo()->GetClassName() );
189 switch (gdk_event
->keyval
)
191 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
192 case GDK_Tab
: key_code
= WXK_TAB
; break;
193 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
194 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
195 case GDK_Return
: key_code
= WXK_RETURN
; break;
196 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
197 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
198 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
199 case GDK_Delete
: key_code
= WXK_DELETE
; break;
200 case GDK_Home
: key_code
= WXK_HOME
; break;
201 case GDK_Left
: key_code
= WXK_LEFT
; break;
202 case GDK_Up
: key_code
= WXK_UP
; break;
203 case GDK_Right
: key_code
= WXK_RIGHT
; break;
204 case GDK_Down
: key_code
= WXK_DOWN
; break;
205 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
206 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
207 case GDK_Next
: key_code
= WXK_NEXT
; break;
208 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
209 case GDK_End
: key_code
= WXK_END
; break;
210 case GDK_Begin
: key_code
= WXK_HOME
; break;
211 case GDK_Select
: key_code
= WXK_SELECT
; break;
212 case GDK_Print
: key_code
= WXK_PRINT
; break;
213 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
214 case GDK_Insert
: key_code
= WXK_INSERT
; break;
215 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
216 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
217 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
218 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
219 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
220 case GDK_KP_Up
: key_code
= WXK_UP
; break;
221 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
222 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
223 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
224 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
225 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
226 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
227 case GDK_KP_End
: key_code
= WXK_END
; break;
228 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
229 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
230 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
231 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
232 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
233 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
234 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
235 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
236 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
237 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
238 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
239 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
240 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
241 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
242 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
243 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
244 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
245 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
246 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
247 case GDK_F1
: key_code
= WXK_F1
; break;
248 case GDK_F2
: key_code
= WXK_F2
; break;
249 case GDK_F3
: key_code
= WXK_F3
; break;
250 case GDK_F4
: key_code
= WXK_F4
; break;
251 case GDK_F5
: key_code
= WXK_F5
; break;
252 case GDK_F6
: key_code
= WXK_F6
; break;
253 case GDK_F7
: key_code
= WXK_F7
; break;
254 case GDK_F8
: key_code
= WXK_F8
; break;
255 case GDK_F9
: key_code
= WXK_F9
; break;
256 case GDK_F10
: key_code
= WXK_F10
; break;
257 case GDK_F11
: key_code
= WXK_F11
; break;
258 case GDK_F12
: key_code
= WXK_F12
; break;
261 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
262 key_code
= gdk_event
->keyval
;
266 if (!key_code
) return FALSE
;
268 wxKeyEvent
event( wxEVT_CHAR
);
269 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
270 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
271 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
272 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
273 event
.m_keyCode
= key_code
;
276 event
.SetEventObject( win
);
278 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
282 wxWindow
*ancestor
= win
;
285 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
288 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
289 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
292 ancestor
= ancestor
->GetParent();
298 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
299 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
305 //-----------------------------------------------------------------------------
306 // "button_press_event"
307 //-----------------------------------------------------------------------------
309 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
311 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
313 if (g_blockEventsOnDrag
) return TRUE
;
317 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
319 gtk_widget_grab_focus (win
->m_wxwindow
);
322 printf( "GrabFocus from " );
323 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
324 printf( win->GetClassInfo()->GetClassName() );
331 if (!win
->HasVMT()) return TRUE
;
334 printf( "OnButtonPress from " );
335 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
336 printf( win->GetClassInfo()->GetClassName() );
340 wxEventType event_type
= wxEVT_LEFT_DOWN
;
342 if (gdk_event
->button
== 1)
344 switch (gdk_event
->type
)
346 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
347 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
351 else if (gdk_event
->button
== 2)
353 switch (gdk_event
->type
)
355 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
356 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
360 else if (gdk_event
->button
== 3)
362 switch (gdk_event
->type
)
364 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
365 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
370 wxMouseEvent
event( event_type
);
371 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
372 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
373 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
374 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
375 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
376 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
377 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
379 event
.m_x
= (long)gdk_event
->x
;
380 event
.m_y
= (long)gdk_event
->y
;
382 // Some control don't have their own X window and thus cannot get
387 wxNode
*node
= win
->GetChildren()->First();
390 wxWindow
*child
= (wxWindow
*)node
->Data();
391 if ((child
->m_x
<= event
.m_x
) &&
392 (child
->m_y
<= event
.m_y
) &&
393 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
394 (child
->m_y
+child
->m_height
>= event
.m_y
))
397 event
.m_x
-= child
->m_x
;
398 event
.m_y
-= child
->m_y
;
405 event
.SetEventObject( win
);
407 gs_timeLastClick
= gdk_event
->time
;
409 if (win
->GetEventHandler()->ProcessEvent( event
))
410 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
415 //-----------------------------------------------------------------------------
416 // "button_release_event"
417 //-----------------------------------------------------------------------------
419 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
421 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
423 if (g_blockEventsOnDrag
) return TRUE
;
425 if (!win
->HasVMT()) return TRUE
;
428 printf( "OnButtonRelease from " );
429 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
430 printf( win->GetClassInfo()->GetClassName() );
434 wxEventType event_type
= wxEVT_NULL
;
436 switch (gdk_event
->button
)
438 case 1: event_type
= wxEVT_LEFT_UP
; break;
439 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
440 case 3: event_type
= wxEVT_RIGHT_UP
; break;
443 wxMouseEvent
event( event_type
);
444 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
445 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
446 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
447 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
448 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
449 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
450 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
451 event
.m_x
= (long)gdk_event
->x
;
452 event
.m_y
= (long)gdk_event
->y
;
454 // Some control don't have their own X window and thus cannot get
459 wxNode
*node
= win
->GetChildren()->First();
462 wxWindow
*child
= (wxWindow
*)node
->Data();
463 if ((child
->m_x
<= event
.m_x
) &&
464 (child
->m_y
<= event
.m_y
) &&
465 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
466 (child
->m_y
+child
->m_height
>= event
.m_y
))
469 event
.m_x
-= child
->m_x
;
470 event
.m_y
-= child
->m_y
;
477 event
.SetEventObject( win
);
479 if (win
->GetEventHandler()->ProcessEvent( event
))
480 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
485 //-----------------------------------------------------------------------------
486 // "motion_notify_event"
487 //-----------------------------------------------------------------------------
489 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
491 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
493 if (g_blockEventsOnDrag
) return TRUE
;
495 if (!win
->HasVMT()) return TRUE
;
498 printf( "OnMotion from " );
499 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
500 printf( win->GetClassInfo()->GetClassName() );
504 wxMouseEvent
event( wxEVT_MOTION
);
505 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
506 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
507 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
508 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
509 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
510 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
511 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
513 event
.m_x
= (long)gdk_event
->x
;
514 event
.m_y
= (long)gdk_event
->y
;
516 // Some control don't have their own X window and thus cannot get
521 wxNode
*node
= win
->GetChildren()->First();
524 wxWindow
*child
= (wxWindow
*)node
->Data();
525 if ((child
->m_x
<= event
.m_x
) &&
526 (child
->m_y
<= event
.m_y
) &&
527 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
528 (child
->m_y
+child
->m_height
>= event
.m_y
))
531 event
.m_x
-= child
->m_x
;
532 event
.m_y
-= child
->m_y
;
539 event
.SetEventObject( win
);
541 if (win
->GetEventHandler()->ProcessEvent( event
))
542 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
547 //-----------------------------------------------------------------------------
549 //-----------------------------------------------------------------------------
551 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
553 if (g_blockEventsOnDrag
) return TRUE
;
556 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
558 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
560 printf( "SetFocus flag from " );
561 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
562 printf( win->GetClassInfo()->GetClassName() );
568 if (!win
->HasVMT()) return TRUE
;
571 printf( "OnSetFocus from " );
572 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
573 printf( win->GetClassInfo()->GetClassName() );
575 printf( WXSTRINGCAST win->GetLabel() );
579 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
580 event
.SetEventObject( win
);
582 if (win
->GetEventHandler()->ProcessEvent( event
))
583 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
588 //-----------------------------------------------------------------------------
590 //-----------------------------------------------------------------------------
592 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
594 if (g_blockEventsOnDrag
) return TRUE
;
597 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
598 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
601 if (!win
->HasVMT()) return TRUE
;
604 printf( "OnKillFocus from " );
605 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
606 printf( win->GetClassInfo()->GetClassName() );
610 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
611 event
.SetEventObject( win
);
613 if (win
->GetEventHandler()->ProcessEvent( event
))
614 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
619 //-----------------------------------------------------------------------------
620 // "enter_notify_event"
621 //-----------------------------------------------------------------------------
623 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
625 if (widget
->window
!= gdk_event
->window
) return TRUE
;
627 if (g_blockEventsOnDrag
) return TRUE
;
629 if (!win
->HasVMT()) return TRUE
;
632 printf( "OnEnter from " );
633 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
634 printf( win->GetClassInfo()->GetClassName() );
638 if ((widget
->window
) && (win
->m_cursor
))
639 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
641 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
642 event
.SetEventObject( win
);
644 if (win
->GetEventHandler()->ProcessEvent( event
))
645 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
650 //-----------------------------------------------------------------------------
651 // "leave_notify_event"
652 //-----------------------------------------------------------------------------
654 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
656 if (widget
->window
!= gdk_event
->window
) return TRUE
;
658 if (g_blockEventsOnDrag
) return TRUE
;
660 if (!win
->HasVMT()) return TRUE
;
663 printf( "OnLeave from " );
664 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
665 printf( win->GetClassInfo()->GetClassName() );
669 if ((widget
->window
) && (win
->m_cursor
))
670 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
672 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
673 event
.SetEventObject( win
);
675 if (win
->GetEventHandler()->ProcessEvent( event
))
676 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
681 //-----------------------------------------------------------------------------
682 // "value_changed" from m_vAdjust
683 //-----------------------------------------------------------------------------
685 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
687 if (g_blockEventsOnDrag
) return;
690 printf( "OnVScroll from " );
691 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
692 printf( win->GetClassInfo()->GetClassName() );
696 if (!win
->HasVMT()) return;
698 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
699 if (fabs(diff
) < 0.2) return;
701 wxEventType command
= wxEVT_NULL
;
703 float line_step
= win
->m_vAdjust
->step_increment
;
704 float page_step
= win
->m_vAdjust
->page_increment
;
706 if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
707 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
708 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
709 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
710 else command
= wxEVT_SCROLL_THUMBTRACK
;
712 int value
= (int)(win
->m_vAdjust
->value
+0.5);
714 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
715 event
.SetEventObject( win
);
716 win
->GetEventHandler()->ProcessEvent( event
);
719 //-----------------------------------------------------------------------------
720 // "value_changed" from m_hAdjust
721 //-----------------------------------------------------------------------------
723 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
725 if (g_blockEventsOnDrag
) return;
728 printf( "OnHScroll from " );
729 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
730 printf( win->GetClassInfo()->GetClassName() );
734 if (!win
->HasVMT()) return;
736 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
737 if (fabs(diff
) < 0.2) return;
739 wxEventType command
= wxEVT_NULL
;
741 float line_step
= win
->m_hAdjust
->step_increment
;
742 float page_step
= win
->m_hAdjust
->page_increment
;
744 if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
745 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
746 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
747 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
748 else command
= wxEVT_SCROLL_THUMBTRACK
;
750 int value
= (int)(win
->m_hAdjust
->value
+0.5);
752 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
753 event
.SetEventObject( win
);
754 win
->GetEventHandler()->ProcessEvent( event
);
757 //-----------------------------------------------------------------------------
758 // "changed" from m_vAdjust
759 //-----------------------------------------------------------------------------
761 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
763 if (g_blockEventsOnDrag
) return;
766 printf( "OnVScroll change from " );
767 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
768 printf( win->GetClassInfo()->GetClassName() );
772 if (!win
->HasVMT()) return;
774 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
775 int value
= (int)(win
->m_vAdjust
->value
+0.5);
777 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
778 event
.SetEventObject( win
);
779 win
->GetEventHandler()->ProcessEvent( event
);
782 //-----------------------------------------------------------------------------
783 // "changed" from m_hAdjust
784 //-----------------------------------------------------------------------------
786 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
788 if (g_blockEventsOnDrag
) return;
791 printf( "OnHScroll change from " );
792 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
793 printf( win->GetClassInfo()->GetClassName() );
797 if (!win
->HasVMT()) return;
799 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
800 int value
= (int)(win
->m_hAdjust
->value
+0.5);
802 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
803 event
.SetEventObject( win
);
804 win
->GetEventHandler()->ProcessEvent( event
);
807 //-----------------------------------------------------------------------------
808 // "button_press_event" from scrollbar
809 //-----------------------------------------------------------------------------
811 static gint
gtk_scrollbar_button_press_callback( GtkRange
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
813 if (gdk_event
->window
!= widget
->slider
) return FALSE
;
815 win
->m_isScrolling
= TRUE
;
820 //-----------------------------------------------------------------------------
821 // "button_release_event" from scrollbar
822 //-----------------------------------------------------------------------------
824 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
826 if (gdk_event
->window
!= widget
->slider
) return FALSE
;
828 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
830 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
831 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
833 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
835 win
->m_isScrolling
= FALSE
;
840 //-----------------------------------------------------------------------------
841 // "drop_data_available_event"
842 //-----------------------------------------------------------------------------
844 static void gtk_window_drop_callback( GtkWidget
*widget
, GdkEventDropDataAvailable
*event
, wxWindow
*win
)
846 if (!win
->HasVMT()) return;
848 if (win
->GetDropTarget())
852 gdk_window_get_pointer( widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
854 printf( "Drop data is of type %s.\n", event
->data_type
);
856 win
->GetDropTarget()->OnDrop( x
, y
, (const void*)event
->data
, (size_t)event
->data_numbytes
);
860 g_free (event->dropdataavailable.data);
861 g_free (event->dropdataavailable.data_type);
865 //-----------------------------------------------------------------------------
867 //-----------------------------------------------------------------------------
869 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
871 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
872 EVT_SIZE(wxWindow::OnSize
)
873 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
874 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
875 EVT_IDLE(wxWindow::OnIdle
)
880 m_widget
= (GtkWidget
*) NULL
;
881 m_wxwindow
= (GtkWidget
*) NULL
;
882 m_parent
= (wxWindow
*) NULL
;
883 m_children
.DeleteContents( FALSE
);
893 m_eventHandler
= this;
894 m_windowValidator
= (wxValidator
*) NULL
;
896 m_cursor
= (wxCursor
*) NULL
;
897 m_font
= *wxSWISS_FONT
;
899 m_windowName
= "noname";
900 m_constraints
= (wxLayoutConstraints
*) NULL
;
901 m_constraintsInvolvedIn
= (wxList
*) NULL
;
902 m_windowSizer
= (wxSizer
*) NULL
;
903 m_sizerParent
= (wxWindow
*) NULL
;
904 m_autoLayout
= FALSE
;
908 m_hasScrolling
= FALSE
;
909 m_isScrolling
= FALSE
;
910 m_hAdjust
= (GtkAdjustment
*) NULL
;
911 m_vAdjust
= (GtkAdjustment
*) NULL
;
912 m_oldHorizontalPos
= 0.0;
913 m_oldVerticalPos
= 0.0;
916 m_pDropTarget
= (wxDropTarget
*) NULL
;
918 m_scrollGC
= (GdkGC
*) NULL
;
919 m_widgetStyle
= (GtkStyle
*) NULL
;
922 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
923 const wxPoint
&pos
, const wxSize
&size
,
924 long style
, const wxString
&name
)
930 m_cursor
= (wxCursor
*) NULL
;
932 PreCreation( parent
, id
, pos
, size
, style
, name
);
934 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
935 m_hasScrolling
= TRUE
;
937 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
939 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
940 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
942 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
943 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
945 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
946 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
948 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
949 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
951 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
952 scroll_class
->scrollbar_spacing
= 0;
954 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
956 m_oldHorizontalPos
= 0.0;
957 m_oldVerticalPos
= 0.0;
959 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
960 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
962 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
963 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
964 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
965 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
967 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
968 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
969 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
970 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
972 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
974 if (m_windowStyle
& wxRAISED_BORDER
)
976 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
978 else if (m_windowStyle
& wxSUNKEN_BORDER
)
980 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
984 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
987 m_wxwindow
= gtk_myfixed_new();
989 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
991 if (m_windowStyle
& wxTAB_TRAVERSAL
== wxTAB_TRAVERSAL
)
992 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
994 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
996 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
998 // shut the viewport up
999 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1000 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1002 // I _really_ don't want scrollbars in the beginning
1003 m_vAdjust
->lower
= 0.0;
1004 m_vAdjust
->upper
= 1.0;
1005 m_vAdjust
->value
= 0.0;
1006 m_vAdjust
->step_increment
= 1.0;
1007 m_vAdjust
->page_increment
= 1.0;
1008 m_vAdjust
->page_size
= 5.0;
1009 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1010 m_hAdjust
->lower
= 0.0;
1011 m_hAdjust
->upper
= 1.0;
1012 m_hAdjust
->value
= 0.0;
1013 m_hAdjust
->step_increment
= 1.0;
1014 m_hAdjust
->page_increment
= 1.0;
1015 m_hAdjust
->page_size
= 5.0;
1016 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1018 gtk_widget_show( m_wxwindow
);
1027 wxWindow::~wxWindow()
1031 if (m_pDropTarget
) delete m_pDropTarget
;
1033 if (m_parent
) m_parent
->RemoveChild( this );
1034 if (m_widget
) Show( FALSE
);
1038 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1040 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1042 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1044 if (m_widget
) gtk_widget_destroy( m_widget
);
1048 DeleteRelatedConstraints();
1051 // This removes any dangling pointers to this window
1052 // in other windows' constraintsInvolvedIn lists.
1053 UnsetConstraints(m_constraints
);
1054 delete m_constraints
;
1055 m_constraints
= (wxLayoutConstraints
*) NULL
;
1059 delete m_windowSizer
;
1060 m_windowSizer
= (wxSizer
*) NULL
;
1062 // If this is a child of a sizer, remove self from parent
1063 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1065 // Just in case the window has been Closed, but
1066 // we're then deleting immediately: don't leave
1067 // dangling pointers.
1068 wxPendingDelete
.DeleteObject(this);
1070 // Just in case we've loaded a top-level window via
1071 // wxWindow::LoadNativeDialog but we weren't a dialog
1073 wxTopLevelWindows
.DeleteObject(this);
1075 if (m_windowValidator
) delete m_windowValidator
;
1078 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1079 const wxPoint
&pos
, const wxSize
&size
,
1080 long style
, const wxString
&name
)
1082 if (m_needParent
&& (parent
== NULL
))
1083 wxFatalError( "Need complete parent.", name
);
1085 m_widget
= (GtkWidget
*) NULL
;
1088 m_children
.DeleteContents( FALSE
);
1092 if (m_width
== -1) m_width
= 20;
1094 if (m_height
== -1) m_height
= 20;
1100 m_eventHandler
= this;
1103 if (m_cursor
== NULL
)
1104 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1105 m_font
= *wxSWISS_FONT
;
1106 // m_backgroundColour = wxWHITE;
1107 // m_foregroundColour = wxBLACK;
1108 m_windowStyle
= style
;
1109 m_windowName
= name
;
1110 m_constraints
= (wxLayoutConstraints
*) NULL
;
1111 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1112 m_windowSizer
= (wxSizer
*) NULL
;
1113 m_sizerParent
= (wxWindow
*) NULL
;
1114 m_autoLayout
= FALSE
;
1115 m_hasScrolling
= FALSE
;
1116 m_isScrolling
= FALSE
;
1117 m_pDropTarget
= (wxDropTarget
*) NULL
;
1119 m_windowValidator
= (wxValidator
*) NULL
;
1120 m_scrollGC
= (GdkGC
*) NULL
;
1121 m_widgetStyle
= (GtkStyle
*) NULL
;
1124 void wxWindow::PostCreation()
1126 if (m_parent
) m_parent
->AddChild( this );
1130 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1131 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1133 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1134 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1137 ConnectWidget( GetConnectWidget() );
1139 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1141 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1143 SetCursor( *wxSTANDARD_CURSOR
);
1148 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1150 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1151 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1153 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1154 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1156 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1157 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1159 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1160 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1162 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1163 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1165 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1166 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1168 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1169 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1171 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1172 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1175 bool wxWindow::HasVMT()
1180 bool wxWindow::Close( bool force
)
1182 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1184 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1185 event
.SetEventObject(this);
1186 event
.SetForce(force
);
1188 return GetEventHandler()->ProcessEvent(event
);
1191 bool wxWindow::Destroy()
1193 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1200 bool wxWindow::DestroyChildren()
1205 while ((node
= GetChildren()->First()) != (wxNode
*)NULL
)
1208 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1211 if (GetChildren()->Member(child
)) delete node
;
1218 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1220 // are we to set fonts here ?
1223 void wxWindow::ImplementSetSize()
1225 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1226 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1227 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_minWidth
;
1228 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_minHeight
;
1229 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1232 void wxWindow::ImplementSetPosition()
1234 if (IS_KIND_OF(this,wxFrame
) || IS_KIND_OF(this,wxDialog
))
1236 if ((m_x
!= -1) || (m_y
!= -1))
1237 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
1243 wxFAIL_MSG( "wxWindow::SetSize error.\n" );
1247 if ((m_parent
) && (m_parent
->m_wxwindow
))
1248 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y
);
1250 // Don't do anything for children of wxNotebook and wxMDIChildFrame
1253 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1255 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1257 if (m_resizing
) return; // I don't like recursions
1265 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1267 if (newX
== -1) newX
= m_x
;
1268 if (newY
== -1) newY
= m_y
;
1269 if (newW
== -1) newW
= m_width
;
1270 if (newH
== -1) newH
= m_height
;
1273 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1275 if (newW
== -1) newW
= 80;
1278 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1280 if (newH
== -1) newH
= 26;
1283 if ((m_x
!= newX
) || (m_y
!= newY
) || (!m_sizeSet
))
1287 ImplementSetPosition();
1289 if ((m_width
!= newW
) || (m_height
!= newH
) || (!m_sizeSet
))
1297 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1298 event
.SetEventObject( this );
1299 ProcessEvent( event
);
1304 void wxWindow::SetSize( int width
, int height
)
1306 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1309 void wxWindow::Move( int x
, int y
)
1311 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1314 void wxWindow::GetSize( int *width
, int *height
) const
1316 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1318 if (width
) (*width
) = m_width
;
1319 if (height
) (*height
) = m_height
;
1322 void wxWindow::SetClientSize( int width
, int height
)
1324 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1328 SetSize( width
, height
);
1335 if (!m_hasScrolling
)
1338 do we have sunken dialogs ?
1340 GtkStyleClass *window_class = m_wxwindow->style->klass;
1342 dw += 2 * window_class->xthickness;
1343 dh += 2 * window_class->ythickness;
1348 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1349 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1351 GtkWidget
*viewport
= scroll_window
->viewport
;
1352 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1354 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1355 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1357 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1358 (m_windowStyle
& wxSUNKEN_BORDER
))
1360 dw
+= 2 * viewport_class
->xthickness
;
1361 dh
+= 2 * viewport_class
->ythickness
;
1364 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1366 dw
+= vscrollbar
->allocation
.width
;
1367 dw
+= scroll_class
->scrollbar_spacing
;
1370 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1372 dh
+= hscrollbar
->allocation
.height
;
1373 dw
+= scroll_class
->scrollbar_spacing
;
1377 SetSize( width
+dw
, height
+dh
);
1381 void wxWindow::GetClientSize( int *width
, int *height
) const
1383 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1387 if (width
) (*width
) = m_width
;
1388 if (height
) (*height
) = m_height
;
1395 if (!m_hasScrolling
)
1398 do we have sunken dialogs ?
1400 GtkStyleClass *window_class = m_wxwindow->style->klass;
1402 dw += 2 * window_class->xthickness;
1403 dh += 2 * window_class->ythickness;
1408 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1409 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1411 GtkWidget
*viewport
= scroll_window
->viewport
;
1412 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1414 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1415 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1417 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1418 (m_windowStyle
& wxSUNKEN_BORDER
))
1420 dw
+= 2 * viewport_class
->xthickness
;
1421 dh
+= 2 * viewport_class
->ythickness
;
1424 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1426 // dw += vscrollbar->allocation.width;
1427 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1428 dw
+= scroll_class
->scrollbar_spacing
;
1431 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1433 // dh += hscrollbar->allocation.height;
1435 dh
+= scroll_class
->scrollbar_spacing
;
1439 if (width
) (*width
) = m_width
- dw
;
1440 if (height
) (*height
) = m_height
- dh
;
1444 void wxWindow::GetPosition( int *x
, int *y
) const
1446 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1452 void wxWindow::ClientToScreen( int *x
, int *y
)
1454 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1456 GdkWindow
*source
= (GdkWindow
*) NULL
;
1458 source
= m_wxwindow
->window
;
1460 source
= m_widget
->window
;
1464 gdk_window_get_origin( source
, &org_x
, &org_y
);
1468 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1470 org_x
+= m_widget
->allocation
.x
;
1471 org_y
+= m_widget
->allocation
.y
;
1479 void wxWindow::ScreenToClient( int *x
, int *y
)
1481 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1483 GdkWindow
*source
= (GdkWindow
*) NULL
;
1485 source
= m_wxwindow
->window
;
1487 source
= m_widget
->window
;
1491 gdk_window_get_origin( source
, &org_x
, &org_y
);
1495 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1497 org_x
+= m_widget
->allocation
.x
;
1498 org_y
+= m_widget
->allocation
.y
;
1506 void wxWindow::Centre( int direction
)
1508 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1510 if (IS_KIND_OF(this,wxDialog
) || IS_KIND_OF(this,wxFrame
))
1512 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (gdk_screen_width () - m_width
) / 2;
1513 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (gdk_screen_height () - m_height
) / 2;
1514 ImplementSetPosition();
1522 m_parent
->GetSize( &p_w
, &p_h
);
1523 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (p_w
- m_width
) / 2;
1524 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (p_h
- m_height
) / 2;
1525 ImplementSetPosition();
1530 void wxWindow::Fit()
1532 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1536 wxNode
*node
= GetChildren()->First();
1539 wxWindow
*win
= (wxWindow
*)node
->Data();
1541 win
->GetPosition(&wx
, &wy
);
1542 win
->GetSize(&ww
, &wh
);
1543 if ( wx
+ ww
> maxX
)
1545 if ( wy
+ wh
> maxY
)
1548 node
= node
->Next();
1550 SetClientSize(maxX
+ 5, maxY
+ 10);
1553 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1555 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1563 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1565 //if (GetAutoLayout()) Layout();
1568 bool wxWindow::Show( bool show
)
1570 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1573 gtk_widget_show( m_widget
);
1575 gtk_widget_hide( m_widget
);
1580 void wxWindow::Enable( bool enable
)
1582 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1584 m_isEnabled
= enable
;
1585 gtk_widget_set_sensitive( m_widget
, enable
);
1586 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1589 int wxWindow::GetCharHeight() const
1591 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1595 wxFAIL_MSG( "invalid font" );
1599 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1600 return font
->ascent
+ font
->descent
;
1603 int wxWindow::GetCharWidth() const
1605 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1609 wxFAIL_MSG( "invalid font" );
1613 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1614 return gdk_string_width( font
, "H" );
1617 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1618 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1620 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1622 wxFont fontToUse
= m_font
;
1623 if (theFont
) fontToUse
= *theFont
;
1625 if (!fontToUse
.Ok())
1627 wxFAIL_MSG( "invalid font" );
1630 wxASSERT_MSG( (m_font
.Ok()), "invalid font" );
1632 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1633 if (x
) (*x
) = gdk_string_width( font
, string
);
1634 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1635 if (descent
) (*descent
) = font
->descent
;
1636 if (externalLeading
) (*externalLeading
) = 0; // ??
1639 void wxWindow::MakeModal( bool modal
)
1642 // Disable all other windows
1643 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1645 wxNode
*node
= wxTopLevelWindows
.First();
1648 wxWindow
*win
= (wxWindow
*)node
->Data();
1650 win
->Enable(!modal
);
1652 node
= node
->Next();
1657 void wxWindow::SetFocus()
1659 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1661 GtkWidget
*connect_widget
= GetConnectWidget();
1664 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) && !GTK_WIDGET_HAS_FOCUS (connect_widget
) )
1666 gtk_widget_grab_focus (connect_widget
);
1671 bool wxWindow::OnClose()
1676 void wxWindow::AddChild( wxWindow
*child
)
1678 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1679 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window need client area" );
1680 wxASSERT_MSG( (child
!= NULL
), "invalid child" );
1681 wxASSERT_MSG( (child
->m_widget
!= NULL
), "invalid child" );
1683 // Addchild is (often) called before the program
1684 // has left the parents constructor so that no
1685 // virtual tables work yet. The approach below
1686 // practically imitates virtual tables, i.e. it
1687 // implements a different AddChild() behaviour
1688 // for wxFrame, wxDialog, wxWindow and
1689 // wxMDIParentFrame.
1691 // wxFrame and wxDialog as children aren't placed into the parents
1693 if (( IS_KIND_OF(child
,wxFrame
) || IS_KIND_OF(child
,wxDialog
) ) /*&&
1694 (!IS_KIND_OF(child,wxMDIChildFrame))*/)
1696 m_children
.Append( child
);
1698 if ((child
->m_x
!= -1) && (child
->m_y
!= -1))
1699 gtk_widget_set_uposition( child
->m_widget
, child
->m_x
, child
->m_y
);
1704 // In the case of an wxMDIChildFrame descendant, we use the
1705 // client windows's AddChild()
1707 if (IS_KIND_OF(this,wxMDIParentFrame
))
1709 if (IS_KIND_OF(child
,wxMDIChildFrame
))
1711 wxMDIClientWindow
*client
= ((wxMDIParentFrame
*)this)->GetClientWindow();
1714 client
->AddChild( child
);
1720 // wxNotebook is very special, so it has a private AddChild()
1722 if (IS_KIND_OF(this,wxNotebook
))
1724 wxNotebook
*tab
= (wxNotebook
*)this;
1725 tab
->AddChild( child
);
1729 // wxFrame has a private AddChild
1731 if (IS_KIND_OF(this,wxFrame
) && !IS_KIND_OF(this,wxMDIChildFrame
))
1733 wxFrame
*frame
= (wxFrame
*)this;
1734 frame
->AddChild( child
);
1740 m_children
.Append( child
);
1741 if (m_wxwindow
) gtk_myfixed_put( GTK_MYFIXED(m_wxwindow
), child
->m_widget
,
1742 child
->m_x
, child
->m_y
);
1744 gtk_widget_set_usize( child
->m_widget
, child
->m_width
, child
->m_height
);
1747 wxList
*wxWindow::GetChildren()
1749 return (&m_children
);
1752 void wxWindow::RemoveChild( wxWindow
*child
)
1755 GetChildren()->DeleteObject( child
);
1756 child
->m_parent
= (wxWindow
*) NULL
;
1759 void wxWindow::SetReturnCode( int retCode
)
1761 m_retCode
= retCode
;
1764 int wxWindow::GetReturnCode()
1769 void wxWindow::Raise()
1771 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1773 if (m_widget
) gdk_window_raise( m_widget
->window
);
1776 void wxWindow::Lower()
1778 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1780 if (m_widget
) gdk_window_lower( m_widget
->window
);
1783 wxEvtHandler
*wxWindow::GetEventHandler()
1785 return m_eventHandler
;
1788 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
1790 m_eventHandler
= handler
;
1793 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
1795 handler
->SetNextHandler(GetEventHandler());
1796 SetEventHandler(handler
);
1799 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
1801 if (GetEventHandler())
1803 wxEvtHandler
*handlerA
= GetEventHandler();
1804 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
1805 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
1806 SetEventHandler(handlerB
);
1810 return (wxEvtHandler
*) NULL
;
1816 return (wxEvtHandler
*) NULL
;
1819 wxValidator
*wxWindow::GetValidator()
1821 return m_windowValidator
;
1824 void wxWindow::SetValidator( const wxValidator
& validator
)
1826 if (m_windowValidator
) delete m_windowValidator
;
1827 m_windowValidator
= validator
.Clone();
1828 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
1831 bool wxWindow::IsBeingDeleted()
1836 void wxWindow::SetId( wxWindowID id
)
1841 wxWindowID
wxWindow::GetId()
1846 void wxWindow::SetCursor( const wxCursor
&cursor
)
1848 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1850 if (m_cursor
== NULL
)
1852 wxFAIL_MSG( "wxWindow::SetCursor m_cursor == NULL" );
1853 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1858 if (*((wxCursor
*)&cursor
) == m_cursor
) return;
1863 *m_cursor
= *wxSTANDARD_CURSOR
;
1866 if ((m_widget
) && (m_widget
->window
))
1867 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
1869 if ((m_wxwindow
) && (m_wxwindow
->window
))
1870 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
1873 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
1875 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1877 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
1880 gdk_window_clear_area( m_wxwindow
->window
,
1894 GetClientSize( &w
, &h
);
1896 GdkRectangle gdk_rect
;
1900 gdk_rect
.height
= h
;
1901 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1906 GdkRectangle gdk_rect
;
1907 gdk_rect
.x
= rect
->x
;
1908 gdk_rect
.y
= rect
->y
;
1909 gdk_rect
.width
= rect
->width
;
1910 gdk_rect
.height
= rect
->height
;
1913 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1915 gtk_widget_draw( m_widget
, &gdk_rect
);
1919 wxRegion
wxWindow::GetUpdateRegion() const
1921 return m_updateRegion
;
1924 bool wxWindow::IsExposed( int x
, int y
) const
1926 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
1929 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
1931 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
1934 bool wxWindow::IsExposed( const wxPoint
& pt
) const
1936 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
1939 bool wxWindow::IsExposed( const wxRect
& rect
) const
1941 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
1944 void wxWindow::Clear()
1946 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
1948 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
1951 wxColour
wxWindow::GetBackgroundColour() const
1953 return m_backgroundColour
;
1956 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
1958 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
1960 m_backgroundColour
= colour
;
1961 if (!m_backgroundColour
.Ok()) return;
1965 GdkWindow
*window
= m_wxwindow
->window
;
1966 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
1967 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
1968 gdk_window_clear( window
);
1974 wxColour
wxWindow::GetForegroundColour() const
1976 return m_foregroundColour
;
1979 void wxWindow::SetForegroundColour( const wxColour
&colour
)
1981 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
1983 m_foregroundColour
= colour
;
1984 if (!m_foregroundColour
.Ok()) return;
1989 GtkStyle
*wxWindow::GetWidgetStyle()
1991 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1995 gtk_widget_get_style( m_widget
) );
1997 return m_widgetStyle
;
2000 void wxWindow::SetWidgetStyle()
2002 GtkStyle
*style
= GetWidgetStyle();
2004 gdk_font_unref( style
->font
);
2005 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2007 if (m_foregroundColour
.Ok())
2009 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2010 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2011 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2012 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2015 if (m_backgroundColour
.Ok())
2017 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2018 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2019 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2020 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2021 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2022 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2023 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2024 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2025 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2029 void wxWindow::ApplyWidgetStyle()
2033 bool wxWindow::Validate()
2035 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2037 wxNode
*node
= GetChildren()->First();
2040 wxWindow
*child
= (wxWindow
*)node
->Data();
2041 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2043 node
= node
->Next();
2048 bool wxWindow::TransferDataToWindow()
2050 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2052 wxNode
*node
= GetChildren()->First();
2055 wxWindow
*child
= (wxWindow
*)node
->Data();
2056 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2057 !child
->GetValidator()->TransferToWindow() )
2059 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2062 node
= node
->Next();
2067 bool wxWindow::TransferDataFromWindow()
2069 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2071 wxNode
*node
= GetChildren()->First();
2074 wxWindow
*child
= (wxWindow
*)node
->Data();
2075 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2077 node
= node
->Next();
2082 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2084 m_acceleratorTable
= accel
;
2087 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2089 TransferDataToWindow();
2092 void wxWindow::InitDialog()
2094 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2096 wxInitDialogEvent
event(GetId());
2097 event
.SetEventObject( this );
2098 GetEventHandler()->ProcessEvent(event
);
2101 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2103 menu
->SetInvokingWindow( win
);
2104 wxNode
*node
= menu
->m_items
.First();
2107 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2108 if (menuitem
->IsSubMenu())
2109 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2110 node
= node
->Next();
2114 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2116 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2118 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2120 SetInvokingWindow( menu
, this );
2122 GTK_MENU(menu
->m_menu
),
2123 (GtkWidget
*)NULL
, // parent menu shell
2124 (GtkWidget
*)NULL
, // parent menu item
2125 (GtkMenuPositionFunc
)NULL
,
2126 NULL
, // client data
2127 0, // button used to activate it
2128 0//gs_timeLastClick // the time of activation
2133 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2135 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2137 GtkWidget
*dnd_widget
= GetConnectWidget();
2139 DisconnectDnDWidget( dnd_widget
);
2141 if (m_pDropTarget
) delete m_pDropTarget
;
2142 m_pDropTarget
= dropTarget
;
2144 ConnectDnDWidget( dnd_widget
);
2147 wxDropTarget
*wxWindow::GetDropTarget() const
2149 return m_pDropTarget
;
2152 void wxWindow::ConnectDnDWidget( GtkWidget
*widget
)
2154 if (!m_pDropTarget
) return;
2156 m_pDropTarget
->RegisterWidget( widget
);
2158 gtk_signal_connect( GTK_OBJECT(widget
), "drop_data_available_event",
2159 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
2162 void wxWindow::DisconnectDnDWidget( GtkWidget
*widget
)
2164 if (!m_pDropTarget
) return;
2166 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
2167 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
2169 m_pDropTarget
->UnregisterWidget( widget
);
2172 GtkWidget
* wxWindow::GetConnectWidget()
2174 GtkWidget
*connect_widget
= m_widget
;
2175 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2177 return connect_widget
;
2180 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2182 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2183 return (window
== m_widget
->window
);
2186 void wxWindow::SetFont( const wxFont
&font
)
2188 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2190 if (((wxFont
*)&font
)->Ok())
2193 m_font
= *wxSWISS_FONT
;
2198 wxFont
*wxWindow::GetFont()
2203 void wxWindow::SetWindowStyleFlag( long flag
)
2205 m_windowStyle
= flag
;
2208 long wxWindow::GetWindowStyleFlag() const
2210 return m_windowStyle
;
2213 void wxWindow::CaptureMouse()
2215 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2217 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2219 GtkWidget
*connect_widget
= GetConnectWidget();
2220 gtk_grab_add( connect_widget
);
2221 gdk_pointer_grab ( connect_widget
->window
, FALSE
,
2223 (GDK_BUTTON_PRESS_MASK
|
2224 GDK_BUTTON_RELEASE_MASK
|
2225 GDK_POINTER_MOTION_MASK
),
2226 (GdkWindow
*) NULL
, (GdkCursor
*) NULL
, GDK_CURRENT_TIME
);
2230 void wxWindow::ReleaseMouse()
2232 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2234 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2236 GtkWidget
*connect_widget
= GetConnectWidget();
2237 gtk_grab_remove( connect_widget
);
2238 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2239 g_capturing
= FALSE
;
2242 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2246 wxString
wxWindow::GetTitle() const
2248 return (wxString
&)m_windowName
;
2251 wxString
wxWindow::GetLabel() const
2256 void wxWindow::SetName( const wxString
&name
)
2258 m_windowName
= name
;
2261 wxString
wxWindow::GetName() const
2263 return (wxString
&)m_windowName
;
2266 bool wxWindow::IsShown() const
2271 bool wxWindow::IsRetained()
2276 wxWindow
*wxWindow::FindWindow( long id
)
2278 if (id
== m_windowId
) return this;
2279 wxNode
*node
= m_children
.First();
2282 wxWindow
*child
= (wxWindow
*)node
->Data();
2283 wxWindow
*res
= child
->FindWindow( id
);
2284 if (res
) return res
;
2285 node
= node
->Next();
2287 return (wxWindow
*) NULL
;
2290 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2292 if (name
== m_windowName
) return this;
2293 wxNode
*node
= m_children
.First();
2296 wxWindow
*child
= (wxWindow
*)node
->Data();
2297 wxWindow
*res
= child
->FindWindow( name
);
2298 if (res
) return res
;
2299 node
= node
->Next();
2301 return (wxWindow
*) NULL
;
2304 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2305 int range
, bool refresh
)
2307 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2309 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2311 if (!m_wxwindow
) return;
2313 if (orient
== wxHORIZONTAL
)
2315 float fpos
= (float)pos
;
2316 float frange
= (float)range
;
2317 float fthumb
= (float)thumbVisible
;
2319 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2320 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2322 SetScrollPos( orient
, pos
, refresh
);
2326 m_oldHorizontalPos
= fpos
;
2328 m_hAdjust
->lower
= 0.0;
2329 m_hAdjust
->upper
= frange
;
2330 m_hAdjust
->value
= fpos
;
2331 m_hAdjust
->step_increment
= 1.0;
2332 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2333 m_hAdjust
->page_size
= fthumb
;
2337 float fpos
= (float)pos
;
2338 float frange
= (float)range
;
2339 float fthumb
= (float)thumbVisible
;
2341 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2342 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2344 SetScrollPos( orient
, pos
, refresh
);
2348 m_oldVerticalPos
= fpos
;
2350 m_vAdjust
->lower
= 0.0;
2351 m_vAdjust
->upper
= frange
;
2352 m_vAdjust
->value
= fpos
;
2353 m_vAdjust
->step_increment
= 1.0;
2354 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2355 m_vAdjust
->page_size
= fthumb
;
2358 if (m_wxwindow
->window
)
2360 if (orient
== wxHORIZONTAL
)
2361 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2363 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2365 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2369 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2371 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2373 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2375 if (!m_wxwindow
) return;
2377 if (orient
== wxHORIZONTAL
)
2379 float fpos
= (float)pos
;
2380 m_oldHorizontalPos
= fpos
;
2382 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2383 m_hAdjust
->value
= fpos
;
2387 float fpos
= (float)pos
;
2388 m_oldVerticalPos
= fpos
;
2389 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2390 m_vAdjust
->value
= fpos
;
2395 if (m_wxwindow
->window
)
2397 if (orient
== wxHORIZONTAL
)
2398 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2400 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2405 int wxWindow::GetScrollThumb( int orient
) const
2407 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2409 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2411 if (!m_wxwindow
) return 0;
2413 if (orient
== wxHORIZONTAL
)
2414 return (int)(m_hAdjust
->page_size
+0.5);
2416 return (int)(m_vAdjust
->page_size
+0.5);
2419 int wxWindow::GetScrollPos( int orient
) const
2421 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2423 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2425 if (!m_wxwindow
) return 0;
2427 if (orient
== wxHORIZONTAL
)
2428 return (int)(m_hAdjust
->value
+0.5);
2430 return (int)(m_vAdjust
->value
+0.5);
2433 int wxWindow::GetScrollRange( int orient
) const
2435 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2437 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2439 if (!m_wxwindow
) return 0;
2441 if (orient
== wxHORIZONTAL
)
2442 return (int)(m_hAdjust
->upper
+0.5);
2444 return (int)(m_vAdjust
->upper
+0.5);
2447 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2449 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2451 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2453 if (!m_wxwindow
) return;
2457 GetClientSize( &cw
, &ch
);
2459 int w
= cw
- abs(dx
);
2460 int h
= ch
- abs(dy
);
2461 if ((h
< 0) || (w
< 0))
2468 if (dx
< 0) s_x
= -dx
;
2469 if (dy
< 0) s_y
= -dy
;
2472 if (dx
> 0) d_x
= dx
;
2473 if (dy
> 0) d_y
= dy
;
2477 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2478 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2481 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2482 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2485 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2486 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2487 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2488 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2490 Refresh( TRUE
, &rect
);
2493 //-------------------------------------------------------------------------------------
2495 //-------------------------------------------------------------------------------------
2497 wxLayoutConstraints
*wxWindow::GetConstraints() const
2499 return m_constraints
;
2502 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2506 UnsetConstraints(m_constraints
);
2507 delete m_constraints
;
2509 m_constraints
= constraints
;
2512 // Make sure other windows know they're part of a 'meaningful relationship'
2513 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2514 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2515 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2516 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2517 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2518 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2519 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2520 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2521 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2522 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2523 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2524 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2525 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2526 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2527 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2528 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2534 void wxWindow::SetAutoLayout( bool autoLayout
)
2536 m_autoLayout
= autoLayout
;
2539 bool wxWindow::GetAutoLayout() const
2541 return m_autoLayout
;
2544 wxSizer
*wxWindow::GetSizer() const
2546 return m_windowSizer
;
2549 void wxWindow::SetSizerParent( wxWindow
*win
)
2551 m_sizerParent
= win
;
2554 wxWindow
*wxWindow::GetSizerParent() const
2556 return m_sizerParent
;
2559 // This removes any dangling pointers to this window
2560 // in other windows' constraintsInvolvedIn lists.
2561 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2565 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2566 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2567 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2568 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2569 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2570 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2571 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2572 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2573 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2574 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2575 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2576 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2577 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2578 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2579 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2580 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2584 // Back-pointer to other windows we're involved with, so if we delete
2585 // this window, we must delete any constraints we're involved with.
2586 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2588 if (!m_constraintsInvolvedIn
)
2589 m_constraintsInvolvedIn
= new wxList
;
2590 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2591 m_constraintsInvolvedIn
->Append(otherWin
);
2594 // REMOVE back-pointer to other windows we're involved with.
2595 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2597 if (m_constraintsInvolvedIn
)
2598 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2601 // Reset any constraints that mention this window
2602 void wxWindow::DeleteRelatedConstraints()
2604 if (m_constraintsInvolvedIn
)
2606 wxNode
*node
= m_constraintsInvolvedIn
->First();
2609 wxWindow
*win
= (wxWindow
*)node
->Data();
2610 wxNode
*next
= node
->Next();
2611 wxLayoutConstraints
*constr
= win
->GetConstraints();
2613 // Reset any constraints involving this window
2616 constr
->left
.ResetIfWin((wxWindow
*)this);
2617 constr
->top
.ResetIfWin((wxWindow
*)this);
2618 constr
->right
.ResetIfWin((wxWindow
*)this);
2619 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2620 constr
->width
.ResetIfWin((wxWindow
*)this);
2621 constr
->height
.ResetIfWin((wxWindow
*)this);
2622 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2623 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2628 delete m_constraintsInvolvedIn
;
2629 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2633 void wxWindow::SetSizer(wxSizer
*sizer
)
2635 m_windowSizer
= sizer
;
2637 sizer
->SetSizerParent((wxWindow
*)this);
2644 bool wxWindow::Layout()
2646 if (GetConstraints())
2649 GetClientSize(&w
, &h
);
2650 GetConstraints()->width
.SetValue(w
);
2651 GetConstraints()->height
.SetValue(h
);
2654 // If top level (one sizer), evaluate the sizer's constraints.
2658 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2659 GetSizer()->LayoutPhase1(&noChanges
);
2660 GetSizer()->LayoutPhase2(&noChanges
);
2661 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2666 // Otherwise, evaluate child constraints
2667 ResetConstraints(); // Mark all constraints as unevaluated
2668 DoPhase(1); // Just one phase need if no sizers involved
2670 SetConstraintSizes(); // Recursively set the real window sizes
2676 // Do a phase of evaluating constraints:
2677 // the default behaviour. wxSizers may do a similar
2678 // thing, but also impose their own 'constraints'
2679 // and order the evaluation differently.
2680 bool wxWindow::LayoutPhase1(int *noChanges
)
2682 wxLayoutConstraints
*constr
= GetConstraints();
2685 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
2691 bool wxWindow::LayoutPhase2(int *noChanges
)
2701 // Do a phase of evaluating child constraints
2702 bool wxWindow::DoPhase(int phase
)
2704 int noIterations
= 0;
2705 int maxIterations
= 500;
2709 while ((noChanges
> 0) && (noIterations
< maxIterations
))
2713 wxNode
*node
= GetChildren()->First();
2716 wxWindow
*child
= (wxWindow
*)node
->Data();
2717 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
2719 wxLayoutConstraints
*constr
= child
->GetConstraints();
2722 if (succeeded
.Member(child
))
2727 int tempNoChanges
= 0;
2728 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
2729 noChanges
+= tempNoChanges
;
2732 succeeded
.Append(child
);
2737 node
= node
->Next();
2744 void wxWindow::ResetConstraints()
2746 wxLayoutConstraints
*constr
= GetConstraints();
2749 constr
->left
.SetDone(FALSE
);
2750 constr
->top
.SetDone(FALSE
);
2751 constr
->right
.SetDone(FALSE
);
2752 constr
->bottom
.SetDone(FALSE
);
2753 constr
->width
.SetDone(FALSE
);
2754 constr
->height
.SetDone(FALSE
);
2755 constr
->centreX
.SetDone(FALSE
);
2756 constr
->centreY
.SetDone(FALSE
);
2758 wxNode
*node
= GetChildren()->First();
2761 wxWindow
*win
= (wxWindow
*)node
->Data();
2762 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2763 win
->ResetConstraints();
2764 node
= node
->Next();
2768 // Need to distinguish between setting the 'fake' size for
2769 // windows and sizers, and setting the real values.
2770 void wxWindow::SetConstraintSizes(bool recurse
)
2772 wxLayoutConstraints
*constr
= GetConstraints();
2773 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
2774 constr
->width
.GetDone() && constr
->height
.GetDone())
2776 int x
= constr
->left
.GetValue();
2777 int y
= constr
->top
.GetValue();
2778 int w
= constr
->width
.GetValue();
2779 int h
= constr
->height
.GetValue();
2781 // If we don't want to resize this window, just move it...
2782 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
2783 (constr
->height
.GetRelationship() != wxAsIs
))
2785 // Calls Layout() recursively. AAAGH. How can we stop that.
2786 // Simply take Layout() out of non-top level OnSizes.
2787 SizerSetSize(x
, y
, w
, h
);
2796 char *windowClass
= this->GetClassInfo()->GetClassName();
2799 if (GetName() == "")
2800 winName
= _("unnamed");
2802 winName
= GetName();
2803 wxDebugMsg(_("Constraint(s) not satisfied for window of type %s, name %s:\n"), (const char *)windowClass
, (const char *)winName
);
2804 if (!constr
->left
.GetDone())
2805 wxDebugMsg(_(" unsatisfied 'left' constraint.\n"));
2806 if (!constr
->right
.GetDone())
2807 wxDebugMsg(_(" unsatisfied 'right' constraint.\n"));
2808 if (!constr
->width
.GetDone())
2809 wxDebugMsg(_(" unsatisfied 'width' constraint.\n"));
2810 if (!constr
->height
.GetDone())
2811 wxDebugMsg(_(" unsatisfied 'height' constraint.\n"));
2812 wxDebugMsg(_("Please check constraints: try adding AsIs() constraints.\n"));
2817 wxNode
*node
= GetChildren()->First();
2820 wxWindow
*win
= (wxWindow
*)node
->Data();
2821 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2822 win
->SetConstraintSizes();
2823 node
= node
->Next();
2828 // This assumes that all sizers are 'on' the same
2829 // window, i.e. the parent of this window.
2830 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
2832 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
2833 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
2837 m_sizerParent
->GetPosition(&xp
, &yp
);
2838 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
2843 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
2847 TransformSizerToActual(&xx
, &yy
);
2848 SetSize(xx
, yy
, w
, h
);
2851 void wxWindow::SizerMove(int x
, int y
)
2855 TransformSizerToActual(&xx
, &yy
);
2859 // Only set the size/position of the constraint (if any)
2860 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
2862 wxLayoutConstraints
*constr
= GetConstraints();
2867 constr
->left
.SetValue(x
);
2868 constr
->left
.SetDone(TRUE
);
2872 constr
->top
.SetValue(y
);
2873 constr
->top
.SetDone(TRUE
);
2877 constr
->width
.SetValue(w
);
2878 constr
->width
.SetDone(TRUE
);
2882 constr
->height
.SetValue(h
);
2883 constr
->height
.SetDone(TRUE
);
2888 void wxWindow::MoveConstraint(int x
, int y
)
2890 wxLayoutConstraints
*constr
= GetConstraints();
2895 constr
->left
.SetValue(x
);
2896 constr
->left
.SetDone(TRUE
);
2900 constr
->top
.SetValue(y
);
2901 constr
->top
.SetDone(TRUE
);
2906 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
2908 wxLayoutConstraints
*constr
= GetConstraints();
2911 *w
= constr
->width
.GetValue();
2912 *h
= constr
->height
.GetValue();
2918 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
2920 wxLayoutConstraints
*constr
= GetConstraints();
2923 *w
= constr
->width
.GetValue();
2924 *h
= constr
->height
.GetValue();
2927 GetClientSize(w
, h
);
2930 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
2932 wxLayoutConstraints
*constr
= GetConstraints();
2935 *x
= constr
->left
.GetValue();
2936 *y
= constr
->top
.GetValue();
2942 bool wxWindow::AcceptsFocus() const
2944 return IsEnabled() && IsShown();
2947 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )