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
);
853 win
->GetDropTarget()->m_size
= event
->data_numbytes
;
854 win
->GetDropTarget()->Drop( event
, x
, y
);
858 g_free (event->dropdataavailable.data);
859 g_free (event->dropdataavailable.data_type);
863 //-----------------------------------------------------------------------------
865 //-----------------------------------------------------------------------------
867 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
869 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
870 EVT_SIZE(wxWindow::OnSize
)
871 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
872 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
873 EVT_IDLE(wxWindow::OnIdle
)
878 m_widget
= (GtkWidget
*) NULL
;
879 m_wxwindow
= (GtkWidget
*) NULL
;
880 m_parent
= (wxWindow
*) NULL
;
881 m_children
.DeleteContents( FALSE
);
891 m_eventHandler
= this;
892 m_windowValidator
= (wxValidator
*) NULL
;
894 m_cursor
= (wxCursor
*) NULL
;
895 m_font
= *wxSWISS_FONT
;
897 m_windowName
= "noname";
898 m_constraints
= (wxLayoutConstraints
*) NULL
;
899 m_constraintsInvolvedIn
= (wxList
*) NULL
;
900 m_windowSizer
= (wxSizer
*) NULL
;
901 m_sizerParent
= (wxWindow
*) NULL
;
902 m_autoLayout
= FALSE
;
906 m_hasScrolling
= FALSE
;
907 m_isScrolling
= FALSE
;
908 m_hAdjust
= (GtkAdjustment
*) NULL
;
909 m_vAdjust
= (GtkAdjustment
*) NULL
;
910 m_oldHorizontalPos
= 0.0;
911 m_oldVerticalPos
= 0.0;
914 m_pDropTarget
= (wxDropTarget
*) NULL
;
916 m_scrollGC
= (GdkGC
*) NULL
;
917 m_widgetStyle
= (GtkStyle
*) NULL
;
920 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
921 const wxPoint
&pos
, const wxSize
&size
,
922 long style
, const wxString
&name
)
928 m_cursor
= (wxCursor
*) NULL
;
930 PreCreation( parent
, id
, pos
, size
, style
, name
);
932 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
933 m_hasScrolling
= TRUE
;
935 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
937 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
938 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
940 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
941 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
943 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
944 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
946 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
947 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
949 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
950 scroll_class
->scrollbar_spacing
= 0;
952 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
954 m_oldHorizontalPos
= 0.0;
955 m_oldVerticalPos
= 0.0;
957 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
958 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
960 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
961 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
962 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
963 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
965 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
966 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
967 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
968 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
970 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
972 if (m_windowStyle
& wxRAISED_BORDER
)
974 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
976 else if (m_windowStyle
& wxSUNKEN_BORDER
)
978 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
982 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
985 m_wxwindow
= gtk_myfixed_new();
987 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
989 if (m_windowStyle
& wxTAB_TRAVERSAL
== wxTAB_TRAVERSAL
)
990 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
992 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
994 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
996 // shut the viewport up
997 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
998 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1000 // I _really_ don't want scrollbars in the beginning
1001 m_vAdjust
->lower
= 0.0;
1002 m_vAdjust
->upper
= 1.0;
1003 m_vAdjust
->value
= 0.0;
1004 m_vAdjust
->step_increment
= 1.0;
1005 m_vAdjust
->page_increment
= 1.0;
1006 m_vAdjust
->page_size
= 5.0;
1007 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1008 m_hAdjust
->lower
= 0.0;
1009 m_hAdjust
->upper
= 1.0;
1010 m_hAdjust
->value
= 0.0;
1011 m_hAdjust
->step_increment
= 1.0;
1012 m_hAdjust
->page_increment
= 1.0;
1013 m_hAdjust
->page_size
= 5.0;
1014 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1016 gtk_widget_show( m_wxwindow
);
1025 wxWindow::~wxWindow()
1029 if (m_pDropTarget
) delete m_pDropTarget
;
1031 if (m_parent
) m_parent
->RemoveChild( this );
1032 if (m_widget
) Show( FALSE
);
1036 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1038 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1040 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1042 if (m_widget
) gtk_widget_destroy( m_widget
);
1046 DeleteRelatedConstraints();
1049 // This removes any dangling pointers to this window
1050 // in other windows' constraintsInvolvedIn lists.
1051 UnsetConstraints(m_constraints
);
1052 delete m_constraints
;
1053 m_constraints
= (wxLayoutConstraints
*) NULL
;
1057 delete m_windowSizer
;
1058 m_windowSizer
= (wxSizer
*) NULL
;
1060 // If this is a child of a sizer, remove self from parent
1061 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1063 // Just in case the window has been Closed, but
1064 // we're then deleting immediately: don't leave
1065 // dangling pointers.
1066 wxPendingDelete
.DeleteObject(this);
1068 // Just in case we've loaded a top-level window via
1069 // wxWindow::LoadNativeDialog but we weren't a dialog
1071 wxTopLevelWindows
.DeleteObject(this);
1073 if (m_windowValidator
) delete m_windowValidator
;
1076 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1077 const wxPoint
&pos
, const wxSize
&size
,
1078 long style
, const wxString
&name
)
1080 if (m_needParent
&& (parent
== NULL
))
1081 wxFatalError( "Need complete parent.", name
);
1083 m_widget
= (GtkWidget
*) NULL
;
1086 m_children
.DeleteContents( FALSE
);
1090 if (m_width
== -1) m_width
= 20;
1092 if (m_height
== -1) m_height
= 20;
1098 m_eventHandler
= this;
1101 if (m_cursor
== NULL
)
1102 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1103 m_font
= *wxSWISS_FONT
;
1104 // m_backgroundColour = wxWHITE;
1105 m_foregroundColour
= wxBLACK
;
1106 m_windowStyle
= style
;
1107 m_windowName
= name
;
1108 m_constraints
= (wxLayoutConstraints
*) NULL
;
1109 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1110 m_windowSizer
= (wxSizer
*) NULL
;
1111 m_sizerParent
= (wxWindow
*) NULL
;
1112 m_autoLayout
= FALSE
;
1113 m_hasScrolling
= FALSE
;
1114 m_isScrolling
= FALSE
;
1115 m_pDropTarget
= (wxDropTarget
*) NULL
;
1117 m_windowValidator
= (wxValidator
*) NULL
;
1118 m_scrollGC
= (GdkGC
*) NULL
;
1119 m_widgetStyle
= (GtkStyle
*) NULL
;
1122 void wxWindow::PostCreation()
1124 if (m_parent
) m_parent
->AddChild( this );
1128 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1129 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1131 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1132 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1135 ConnectWidget( GetConnectWidget() );
1137 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1139 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1141 SetCursor( *wxSTANDARD_CURSOR
);
1146 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1148 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1149 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1151 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1152 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1154 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1155 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1157 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1158 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1160 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1161 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1163 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1164 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1166 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1167 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1169 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1170 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1173 bool wxWindow::HasVMT()
1178 bool wxWindow::Close( bool force
)
1180 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1182 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1183 event
.SetEventObject(this);
1184 event
.SetForce(force
);
1186 return GetEventHandler()->ProcessEvent(event
);
1189 bool wxWindow::Destroy()
1191 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1198 bool wxWindow::DestroyChildren()
1203 while ((node
= GetChildren()->First()) != (wxNode
*)NULL
)
1206 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1209 if (GetChildren()->Member(child
)) delete node
;
1216 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1218 // are we to set fonts here ?
1221 void wxWindow::ImplementSetSize()
1223 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1224 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1225 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_minWidth
;
1226 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_minHeight
;
1227 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1230 void wxWindow::ImplementSetPosition()
1232 if (IS_KIND_OF(this,wxFrame
) || IS_KIND_OF(this,wxDialog
))
1234 if ((m_x
!= -1) || (m_y
!= -1))
1235 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
1241 wxFAIL_MSG( "wxWindow::SetSize error.\n" );
1245 if ((m_parent
) && (m_parent
->m_wxwindow
))
1246 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y
);
1248 // Don't do anything for children of wxNotebook and wxMDIChildFrame
1251 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1253 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1255 if (m_resizing
) return; // I don't like recursions
1263 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1265 if (newX
== -1) newX
= m_x
;
1266 if (newY
== -1) newY
= m_y
;
1267 if (newW
== -1) newW
= m_width
;
1268 if (newH
== -1) newH
= m_height
;
1271 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1273 if (newW
== -1) newW
= 80;
1276 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1278 if (newH
== -1) newH
= 26;
1281 if ((m_x
!= newX
) || (m_y
!= newY
) || (!m_sizeSet
))
1285 ImplementSetPosition();
1287 if ((m_width
!= newW
) || (m_height
!= newH
) || (!m_sizeSet
))
1295 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1296 event
.SetEventObject( this );
1297 ProcessEvent( event
);
1302 void wxWindow::SetSize( int width
, int height
)
1304 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1307 void wxWindow::Move( int x
, int y
)
1309 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1312 void wxWindow::GetSize( int *width
, int *height
) const
1314 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1316 if (width
) (*width
) = m_width
;
1317 if (height
) (*height
) = m_height
;
1320 void wxWindow::SetClientSize( int width
, int height
)
1322 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1326 SetSize( width
, height
);
1333 if (!m_hasScrolling
)
1336 do we have sunken dialogs ?
1338 GtkStyleClass *window_class = m_wxwindow->style->klass;
1340 dw += 2 * window_class->xthickness;
1341 dh += 2 * window_class->ythickness;
1346 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1347 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1349 GtkWidget
*viewport
= scroll_window
->viewport
;
1350 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1352 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1353 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1355 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1356 (m_windowStyle
& wxSUNKEN_BORDER
))
1358 dw
+= 2 * viewport_class
->xthickness
;
1359 dh
+= 2 * viewport_class
->ythickness
;
1362 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1364 dw
+= vscrollbar
->allocation
.width
;
1365 dw
+= scroll_class
->scrollbar_spacing
;
1368 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1370 dh
+= hscrollbar
->allocation
.height
;
1371 dw
+= scroll_class
->scrollbar_spacing
;
1375 SetSize( width
+dw
, height
+dh
);
1379 void wxWindow::GetClientSize( int *width
, int *height
) const
1381 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1385 if (width
) (*width
) = m_width
;
1386 if (height
) (*height
) = m_height
;
1393 if (!m_hasScrolling
)
1396 do we have sunken dialogs ?
1398 GtkStyleClass *window_class = m_wxwindow->style->klass;
1400 dw += 2 * window_class->xthickness;
1401 dh += 2 * window_class->ythickness;
1406 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1407 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1409 GtkWidget
*viewport
= scroll_window
->viewport
;
1410 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1412 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1413 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1415 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1416 (m_windowStyle
& wxSUNKEN_BORDER
))
1418 dw
+= 2 * viewport_class
->xthickness
;
1419 dh
+= 2 * viewport_class
->ythickness
;
1422 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1424 // dw += vscrollbar->allocation.width;
1425 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1426 dw
+= scroll_class
->scrollbar_spacing
;
1429 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1431 // dh += hscrollbar->allocation.height;
1433 dh
+= scroll_class
->scrollbar_spacing
;
1437 if (width
) (*width
) = m_width
- dw
;
1438 if (height
) (*height
) = m_height
- dh
;
1442 void wxWindow::GetPosition( int *x
, int *y
) const
1444 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1450 void wxWindow::ClientToScreen( int *x
, int *y
)
1452 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1454 GdkWindow
*source
= (GdkWindow
*) NULL
;
1456 source
= m_wxwindow
->window
;
1458 source
= m_widget
->window
;
1462 gdk_window_get_origin( source
, &org_x
, &org_y
);
1466 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1468 org_x
+= m_widget
->allocation
.x
;
1469 org_y
+= m_widget
->allocation
.y
;
1477 void wxWindow::ScreenToClient( int *x
, int *y
)
1479 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1481 GdkWindow
*source
= (GdkWindow
*) NULL
;
1483 source
= m_wxwindow
->window
;
1485 source
= m_widget
->window
;
1489 gdk_window_get_origin( source
, &org_x
, &org_y
);
1493 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1495 org_x
+= m_widget
->allocation
.x
;
1496 org_y
+= m_widget
->allocation
.y
;
1504 void wxWindow::Centre( int direction
)
1506 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1508 if (IS_KIND_OF(this,wxDialog
) || IS_KIND_OF(this,wxFrame
))
1510 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (gdk_screen_width () - m_width
) / 2;
1511 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (gdk_screen_height () - m_height
) / 2;
1512 ImplementSetPosition();
1520 m_parent
->GetSize( &p_w
, &p_h
);
1521 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (p_w
- m_width
) / 2;
1522 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (p_h
- m_height
) / 2;
1523 ImplementSetPosition();
1528 void wxWindow::Fit()
1530 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1534 wxNode
*node
= GetChildren()->First();
1537 wxWindow
*win
= (wxWindow
*)node
->Data();
1539 win
->GetPosition(&wx
, &wy
);
1540 win
->GetSize(&ww
, &wh
);
1541 if ( wx
+ ww
> maxX
)
1543 if ( wy
+ wh
> maxY
)
1546 node
= node
->Next();
1548 SetClientSize(maxX
+ 5, maxY
+ 10);
1551 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1553 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1561 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1563 //if (GetAutoLayout()) Layout();
1566 bool wxWindow::Show( bool show
)
1568 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1571 gtk_widget_show( m_widget
);
1573 gtk_widget_hide( m_widget
);
1578 void wxWindow::Enable( bool enable
)
1580 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1582 m_isEnabled
= enable
;
1583 gtk_widget_set_sensitive( m_widget
, enable
);
1584 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1587 int wxWindow::GetCharHeight() const
1589 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1593 wxFAIL_MSG( "invalid font" );
1597 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1598 return font
->ascent
+ font
->descent
;
1601 int wxWindow::GetCharWidth() const
1603 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1607 wxFAIL_MSG( "invalid font" );
1611 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1612 return gdk_string_width( font
, "H" );
1615 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1616 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1618 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1620 wxFont fontToUse
= m_font
;
1621 if (theFont
) fontToUse
= *theFont
;
1623 if (!fontToUse
.Ok())
1625 wxFAIL_MSG( "invalid font" );
1628 wxASSERT_MSG( (m_font
.Ok()), "invalid font" );
1630 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1631 if (x
) (*x
) = gdk_string_width( font
, string
);
1632 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1633 if (descent
) (*descent
) = font
->descent
;
1634 if (externalLeading
) (*externalLeading
) = 0; // ??
1637 void wxWindow::MakeModal( bool modal
)
1640 // Disable all other windows
1641 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1643 wxNode
*node
= wxTopLevelWindows
.First();
1646 wxWindow
*win
= (wxWindow
*)node
->Data();
1648 win
->Enable(!modal
);
1650 node
= node
->Next();
1655 void wxWindow::SetFocus()
1657 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1659 GtkWidget
*connect_widget
= GetConnectWidget();
1662 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) && !GTK_WIDGET_HAS_FOCUS (connect_widget
) )
1664 gtk_widget_grab_focus (connect_widget
);
1669 bool wxWindow::OnClose()
1674 void wxWindow::AddChild( wxWindow
*child
)
1676 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1677 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window need client area" );
1678 wxASSERT_MSG( (child
!= NULL
), "invalid child" );
1679 wxASSERT_MSG( (child
->m_widget
!= NULL
), "invalid child" );
1681 // Addchild is (often) called before the program
1682 // has left the parents constructor so that no
1683 // virtual tables work yet. The approach below
1684 // practically imitates virtual tables, i.e. it
1685 // implements a different AddChild() behaviour
1686 // for wxFrame, wxDialog, wxWindow and
1687 // wxMDIParentFrame.
1689 // wxFrame and wxDialog as children aren't placed into the parents
1691 if (( IS_KIND_OF(child
,wxFrame
) || IS_KIND_OF(child
,wxDialog
) ) &&
1692 (!IS_KIND_OF(child
,wxMDIChildFrame
)))
1694 m_children
.Append( child
);
1696 if ((child
->m_x
!= -1) && (child
->m_y
!= -1))
1697 gtk_widget_set_uposition( child
->m_widget
, child
->m_x
, child
->m_y
);
1702 // In the case of an wxMDIChildFrame descendant, we use the
1703 // client windows's AddChild()
1705 if (IS_KIND_OF(this,wxMDIParentFrame
))
1707 if (IS_KIND_OF(child
,wxMDIChildFrame
))
1709 wxMDIClientWindow
*client
= ((wxMDIParentFrame
*)this)->GetClientWindow();
1712 client
->AddChild( child
);
1718 // wxNotebook is very special, so it has a private AddChild()
1720 if (IS_KIND_OF(this,wxNotebook
))
1722 wxNotebook
*tab
= (wxNotebook
*)this;
1723 tab
->AddChild( child
);
1727 // wxFrame has a private AddChild
1729 if (IS_KIND_OF(this,wxFrame
) && !IS_KIND_OF(this,wxMDIChildFrame
))
1731 wxFrame
*frame
= (wxFrame
*)this;
1732 frame
->AddChild( child
);
1738 m_children
.Append( child
);
1739 if (m_wxwindow
) gtk_myfixed_put( GTK_MYFIXED(m_wxwindow
), child
->m_widget
,
1740 child
->m_x
, child
->m_y
);
1742 gtk_widget_set_usize( child
->m_widget
, child
->m_width
, child
->m_height
);
1745 wxList
*wxWindow::GetChildren()
1747 return (&m_children
);
1750 void wxWindow::RemoveChild( wxWindow
*child
)
1753 GetChildren()->DeleteObject( child
);
1754 child
->m_parent
= (wxWindow
*) NULL
;
1757 void wxWindow::SetReturnCode( int retCode
)
1759 m_retCode
= retCode
;
1762 int wxWindow::GetReturnCode()
1767 void wxWindow::Raise()
1769 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1771 if (m_widget
) gdk_window_raise( m_widget
->window
);
1774 void wxWindow::Lower()
1776 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1778 if (m_widget
) gdk_window_lower( m_widget
->window
);
1781 wxEvtHandler
*wxWindow::GetEventHandler()
1783 return m_eventHandler
;
1786 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
1788 m_eventHandler
= handler
;
1791 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
1793 handler
->SetNextHandler(GetEventHandler());
1794 SetEventHandler(handler
);
1797 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
1799 if (GetEventHandler())
1801 wxEvtHandler
*handlerA
= GetEventHandler();
1802 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
1803 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
1804 SetEventHandler(handlerB
);
1808 return (wxEvtHandler
*) NULL
;
1814 return (wxEvtHandler
*) NULL
;
1817 wxValidator
*wxWindow::GetValidator()
1819 return m_windowValidator
;
1822 void wxWindow::SetValidator( const wxValidator
& validator
)
1824 if (m_windowValidator
) delete m_windowValidator
;
1825 m_windowValidator
= validator
.Clone();
1826 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
1829 bool wxWindow::IsBeingDeleted()
1834 void wxWindow::SetId( wxWindowID id
)
1839 wxWindowID
wxWindow::GetId()
1844 void wxWindow::SetCursor( const wxCursor
&cursor
)
1846 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1848 if (m_cursor
== NULL
)
1850 wxFAIL_MSG( "wxWindow::SetCursor m_cursor == NULL" );
1851 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1856 if (*((wxCursor
*)&cursor
) == m_cursor
) return;
1861 *m_cursor
= *wxSTANDARD_CURSOR
;
1864 if ((m_widget
) && (m_widget
->window
))
1865 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
1867 if ((m_wxwindow
) && (m_wxwindow
->window
))
1868 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
1871 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
1873 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1875 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
1878 gdk_window_clear_area( m_wxwindow
->window
,
1892 GetClientSize( &w
, &h
);
1894 GdkRectangle gdk_rect
;
1898 gdk_rect
.height
= h
;
1899 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1904 GdkRectangle gdk_rect
;
1905 gdk_rect
.x
= rect
->x
;
1906 gdk_rect
.y
= rect
->y
;
1907 gdk_rect
.width
= rect
->width
;
1908 gdk_rect
.height
= rect
->height
;
1911 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1913 gtk_widget_draw( m_widget
, &gdk_rect
);
1917 wxRegion
wxWindow::GetUpdateRegion() const
1919 return m_updateRegion
;
1922 bool wxWindow::IsExposed( int x
, int y
) const
1924 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
1927 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
1929 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
1932 bool wxWindow::IsExposed( const wxPoint
& pt
) const
1934 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
1937 bool wxWindow::IsExposed( const wxRect
& rect
) const
1939 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
1942 void wxWindow::Clear()
1944 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
1946 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
1949 wxColour
wxWindow::GetBackgroundColour() const
1951 return m_backgroundColour
;
1954 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
1956 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
1958 m_backgroundColour
= colour
;
1959 if (!m_backgroundColour
.Ok()) return;
1963 GdkWindow
*window
= m_wxwindow
->window
;
1964 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
1965 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
1966 gdk_window_clear( window
);
1970 GtkStyle
*style
= GetWidgetStyle();
1971 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
1972 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
1973 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
1974 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
1975 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
1976 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
1977 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
1978 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
1979 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
1983 wxColour
wxWindow::GetForegroundColour() const
1985 return m_foregroundColour
;
1988 void wxWindow::SetForegroundColour( const wxColour
&colour
)
1990 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
1992 m_foregroundColour
= colour
;
1993 if (!m_foregroundColour
.Ok()) return;
1997 GtkStyle
*style
= GetWidgetStyle();
1998 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
1999 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2000 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2001 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2005 GtkStyle
*wxWindow::GetWidgetStyle()
2010 gtk_widget_get_style( m_widget
) );
2011 return m_widgetStyle
;
2014 bool wxWindow::Validate()
2016 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2018 wxNode
*node
= GetChildren()->First();
2021 wxWindow
*child
= (wxWindow
*)node
->Data();
2022 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2024 node
= node
->Next();
2029 bool wxWindow::TransferDataToWindow()
2031 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2033 wxNode
*node
= GetChildren()->First();
2036 wxWindow
*child
= (wxWindow
*)node
->Data();
2037 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2038 !child
->GetValidator()->TransferToWindow() )
2040 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2043 node
= node
->Next();
2048 bool wxWindow::TransferDataFromWindow()
2050 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2052 wxNode
*node
= GetChildren()->First();
2055 wxWindow
*child
= (wxWindow
*)node
->Data();
2056 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2058 node
= node
->Next();
2063 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2065 m_acceleratorTable
= accel
;
2068 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2070 TransferDataToWindow();
2073 void wxWindow::InitDialog()
2075 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2077 wxInitDialogEvent
event(GetId());
2078 event
.SetEventObject( this );
2079 GetEventHandler()->ProcessEvent(event
);
2082 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2084 menu
->SetInvokingWindow( win
);
2085 wxNode
*node
= menu
->m_items
.First();
2088 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2089 if (menuitem
->IsSubMenu())
2090 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2091 node
= node
->Next();
2095 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2097 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2099 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2101 SetInvokingWindow( menu
, this );
2103 GTK_MENU(menu
->m_menu
),
2104 (GtkWidget
*)NULL
, // parent menu shell
2105 (GtkWidget
*)NULL
, // parent menu item
2106 (GtkMenuPositionFunc
)NULL
,
2107 NULL
, // client data
2108 0, // button used to activate it
2109 0//gs_timeLastClick // the time of activation
2114 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2116 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2118 GtkWidget
*dnd_widget
= GetConnectWidget();
2120 DisconnectDnDWidget( dnd_widget
);
2122 if (m_pDropTarget
) delete m_pDropTarget
;
2123 m_pDropTarget
= dropTarget
;
2125 ConnectDnDWidget( dnd_widget
);
2128 wxDropTarget
*wxWindow::GetDropTarget() const
2130 return m_pDropTarget
;
2133 void wxWindow::ConnectDnDWidget( GtkWidget
*widget
)
2135 if (!m_pDropTarget
) return;
2137 m_pDropTarget
->RegisterWidget( widget
);
2139 gtk_signal_connect( GTK_OBJECT(widget
), "drop_data_available_event",
2140 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
2143 void wxWindow::DisconnectDnDWidget( GtkWidget
*widget
)
2145 if (!m_pDropTarget
) return;
2147 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
2148 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
2150 m_pDropTarget
->UnregisterWidget( widget
);
2153 GtkWidget
* wxWindow::GetConnectWidget()
2155 GtkWidget
*connect_widget
= m_widget
;
2156 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2158 return connect_widget
;
2161 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2163 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2164 return (window
== m_widget
->window
);
2167 void wxWindow::SetFont( const wxFont
&font
)
2169 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2171 if (((wxFont
*)&font
)->Ok())
2174 m_font
= *wxSWISS_FONT
;
2176 GtkStyle
*style
= GetWidgetStyle();
2177 gdk_font_unref( style
->font
);
2178 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2181 wxFont
*wxWindow::GetFont()
2186 void wxWindow::SetWindowStyleFlag( long flag
)
2188 m_windowStyle
= flag
;
2191 long wxWindow::GetWindowStyleFlag() const
2193 return m_windowStyle
;
2196 void wxWindow::CaptureMouse()
2198 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2200 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2202 GtkWidget
*connect_widget
= GetConnectWidget();
2203 gtk_grab_add( connect_widget
);
2204 gdk_pointer_grab ( connect_widget
->window
, FALSE
,
2206 (GDK_BUTTON_PRESS_MASK
|
2207 GDK_BUTTON_RELEASE_MASK
|
2208 GDK_POINTER_MOTION_MASK
),
2209 (GdkWindow
*) NULL
, (GdkCursor
*) NULL
, GDK_CURRENT_TIME
);
2213 void wxWindow::ReleaseMouse()
2215 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2217 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2219 GtkWidget
*connect_widget
= GetConnectWidget();
2220 gtk_grab_remove( connect_widget
);
2221 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2222 g_capturing
= FALSE
;
2225 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2229 wxString
wxWindow::GetTitle() const
2231 return (wxString
&)m_windowName
;
2234 wxString
wxWindow::GetLabel() const
2239 void wxWindow::SetName( const wxString
&name
)
2241 m_windowName
= name
;
2244 wxString
wxWindow::GetName() const
2246 return (wxString
&)m_windowName
;
2249 bool wxWindow::IsShown() const
2254 bool wxWindow::IsRetained()
2259 wxWindow
*wxWindow::FindWindow( long id
)
2261 if (id
== m_windowId
) return this;
2262 wxNode
*node
= m_children
.First();
2265 wxWindow
*child
= (wxWindow
*)node
->Data();
2266 wxWindow
*res
= child
->FindWindow( id
);
2267 if (res
) return res
;
2268 node
= node
->Next();
2270 return (wxWindow
*) NULL
;
2273 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2275 if (name
== m_windowName
) return this;
2276 wxNode
*node
= m_children
.First();
2279 wxWindow
*child
= (wxWindow
*)node
->Data();
2280 wxWindow
*res
= child
->FindWindow( name
);
2281 if (res
) return res
;
2282 node
= node
->Next();
2284 return (wxWindow
*) NULL
;
2287 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2288 int range
, bool refresh
)
2290 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2292 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2294 if (!m_wxwindow
) return;
2296 if (orient
== wxHORIZONTAL
)
2298 float fpos
= (float)pos
;
2299 float frange
= (float)range
;
2300 float fthumb
= (float)thumbVisible
;
2302 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2303 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2305 SetScrollPos( orient
, pos
, refresh
);
2309 m_oldHorizontalPos
= fpos
;
2311 m_hAdjust
->lower
= 0.0;
2312 m_hAdjust
->upper
= frange
;
2313 m_hAdjust
->value
= fpos
;
2314 m_hAdjust
->step_increment
= 1.0;
2315 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2316 m_hAdjust
->page_size
= fthumb
;
2320 float fpos
= (float)pos
;
2321 float frange
= (float)range
;
2322 float fthumb
= (float)thumbVisible
;
2324 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2325 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2327 SetScrollPos( orient
, pos
, refresh
);
2331 m_oldVerticalPos
= fpos
;
2333 m_vAdjust
->lower
= 0.0;
2334 m_vAdjust
->upper
= frange
;
2335 m_vAdjust
->value
= fpos
;
2336 m_vAdjust
->step_increment
= 1.0;
2337 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2338 m_vAdjust
->page_size
= fthumb
;
2341 if (m_wxwindow
->window
)
2343 if (orient
== wxHORIZONTAL
)
2344 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2346 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2348 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2352 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2354 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2356 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2358 if (!m_wxwindow
) return;
2360 if (orient
== wxHORIZONTAL
)
2362 float fpos
= (float)pos
;
2363 m_oldHorizontalPos
= fpos
;
2365 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2366 m_hAdjust
->value
= fpos
;
2370 float fpos
= (float)pos
;
2371 m_oldVerticalPos
= fpos
;
2372 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2373 m_vAdjust
->value
= fpos
;
2378 if (m_wxwindow
->window
)
2380 if (orient
== wxHORIZONTAL
)
2381 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2383 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2388 int wxWindow::GetScrollThumb( int orient
) const
2390 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2392 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2394 if (!m_wxwindow
) return 0;
2396 if (orient
== wxHORIZONTAL
)
2397 return (int)(m_hAdjust
->page_size
+0.5);
2399 return (int)(m_vAdjust
->page_size
+0.5);
2402 int wxWindow::GetScrollPos( int orient
) const
2404 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2406 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2408 if (!m_wxwindow
) return 0;
2410 if (orient
== wxHORIZONTAL
)
2411 return (int)(m_hAdjust
->value
+0.5);
2413 return (int)(m_vAdjust
->value
+0.5);
2416 int wxWindow::GetScrollRange( int orient
) const
2418 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2420 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2422 if (!m_wxwindow
) return 0;
2424 if (orient
== wxHORIZONTAL
)
2425 return (int)(m_hAdjust
->upper
+0.5);
2427 return (int)(m_vAdjust
->upper
+0.5);
2430 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2432 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
2434 wxASSERT_MSG( (m_wxwindow
!= NULL
), "window needs client area" );
2436 if (!m_wxwindow
) return;
2440 GetClientSize( &cw
, &ch
);
2442 int w
= cw
- abs(dx
);
2443 int h
= ch
- abs(dy
);
2444 if ((h
< 0) || (w
< 0))
2451 if (dx
< 0) s_x
= -dx
;
2452 if (dy
< 0) s_y
= -dy
;
2455 if (dx
> 0) d_x
= dx
;
2456 if (dy
> 0) d_y
= dy
;
2460 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2461 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2464 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2465 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2468 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2469 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2470 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2471 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2473 Refresh( TRUE
, &rect
);
2476 //-------------------------------------------------------------------------------------
2478 //-------------------------------------------------------------------------------------
2480 wxLayoutConstraints
*wxWindow::GetConstraints() const
2482 return m_constraints
;
2485 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2489 UnsetConstraints(m_constraints
);
2490 delete m_constraints
;
2492 m_constraints
= constraints
;
2495 // Make sure other windows know they're part of a 'meaningful relationship'
2496 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2497 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2498 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2499 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2500 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2501 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2502 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2503 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2504 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2505 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2506 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2507 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2508 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2509 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2510 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2511 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2517 void wxWindow::SetAutoLayout( bool autoLayout
)
2519 m_autoLayout
= autoLayout
;
2522 bool wxWindow::GetAutoLayout() const
2524 return m_autoLayout
;
2527 wxSizer
*wxWindow::GetSizer() const
2529 return m_windowSizer
;
2532 void wxWindow::SetSizerParent( wxWindow
*win
)
2534 m_sizerParent
= win
;
2537 wxWindow
*wxWindow::GetSizerParent() const
2539 return m_sizerParent
;
2542 // This removes any dangling pointers to this window
2543 // in other windows' constraintsInvolvedIn lists.
2544 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2548 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2549 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2550 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2551 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2552 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2553 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2554 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2555 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2556 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2557 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2558 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2559 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2560 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2561 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2562 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2563 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2567 // Back-pointer to other windows we're involved with, so if we delete
2568 // this window, we must delete any constraints we're involved with.
2569 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2571 if (!m_constraintsInvolvedIn
)
2572 m_constraintsInvolvedIn
= new wxList
;
2573 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2574 m_constraintsInvolvedIn
->Append(otherWin
);
2577 // REMOVE back-pointer to other windows we're involved with.
2578 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2580 if (m_constraintsInvolvedIn
)
2581 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2584 // Reset any constraints that mention this window
2585 void wxWindow::DeleteRelatedConstraints()
2587 if (m_constraintsInvolvedIn
)
2589 wxNode
*node
= m_constraintsInvolvedIn
->First();
2592 wxWindow
*win
= (wxWindow
*)node
->Data();
2593 wxNode
*next
= node
->Next();
2594 wxLayoutConstraints
*constr
= win
->GetConstraints();
2596 // Reset any constraints involving this window
2599 constr
->left
.ResetIfWin((wxWindow
*)this);
2600 constr
->top
.ResetIfWin((wxWindow
*)this);
2601 constr
->right
.ResetIfWin((wxWindow
*)this);
2602 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2603 constr
->width
.ResetIfWin((wxWindow
*)this);
2604 constr
->height
.ResetIfWin((wxWindow
*)this);
2605 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2606 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2611 delete m_constraintsInvolvedIn
;
2612 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2616 void wxWindow::SetSizer(wxSizer
*sizer
)
2618 m_windowSizer
= sizer
;
2620 sizer
->SetSizerParent((wxWindow
*)this);
2627 bool wxWindow::Layout()
2629 if (GetConstraints())
2632 GetClientSize(&w
, &h
);
2633 GetConstraints()->width
.SetValue(w
);
2634 GetConstraints()->height
.SetValue(h
);
2637 // If top level (one sizer), evaluate the sizer's constraints.
2641 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2642 GetSizer()->LayoutPhase1(&noChanges
);
2643 GetSizer()->LayoutPhase2(&noChanges
);
2644 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2649 // Otherwise, evaluate child constraints
2650 ResetConstraints(); // Mark all constraints as unevaluated
2651 DoPhase(1); // Just one phase need if no sizers involved
2653 SetConstraintSizes(); // Recursively set the real window sizes
2659 // Do a phase of evaluating constraints:
2660 // the default behaviour. wxSizers may do a similar
2661 // thing, but also impose their own 'constraints'
2662 // and order the evaluation differently.
2663 bool wxWindow::LayoutPhase1(int *noChanges
)
2665 wxLayoutConstraints
*constr
= GetConstraints();
2668 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
2674 bool wxWindow::LayoutPhase2(int *noChanges
)
2684 // Do a phase of evaluating child constraints
2685 bool wxWindow::DoPhase(int phase
)
2687 int noIterations
= 0;
2688 int maxIterations
= 500;
2692 while ((noChanges
> 0) && (noIterations
< maxIterations
))
2696 wxNode
*node
= GetChildren()->First();
2699 wxWindow
*child
= (wxWindow
*)node
->Data();
2700 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
2702 wxLayoutConstraints
*constr
= child
->GetConstraints();
2705 if (succeeded
.Member(child
))
2710 int tempNoChanges
= 0;
2711 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
2712 noChanges
+= tempNoChanges
;
2715 succeeded
.Append(child
);
2720 node
= node
->Next();
2727 void wxWindow::ResetConstraints()
2729 wxLayoutConstraints
*constr
= GetConstraints();
2732 constr
->left
.SetDone(FALSE
);
2733 constr
->top
.SetDone(FALSE
);
2734 constr
->right
.SetDone(FALSE
);
2735 constr
->bottom
.SetDone(FALSE
);
2736 constr
->width
.SetDone(FALSE
);
2737 constr
->height
.SetDone(FALSE
);
2738 constr
->centreX
.SetDone(FALSE
);
2739 constr
->centreY
.SetDone(FALSE
);
2741 wxNode
*node
= GetChildren()->First();
2744 wxWindow
*win
= (wxWindow
*)node
->Data();
2745 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2746 win
->ResetConstraints();
2747 node
= node
->Next();
2751 // Need to distinguish between setting the 'fake' size for
2752 // windows and sizers, and setting the real values.
2753 void wxWindow::SetConstraintSizes(bool recurse
)
2755 wxLayoutConstraints
*constr
= GetConstraints();
2756 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
2757 constr
->width
.GetDone() && constr
->height
.GetDone())
2759 int x
= constr
->left
.GetValue();
2760 int y
= constr
->top
.GetValue();
2761 int w
= constr
->width
.GetValue();
2762 int h
= constr
->height
.GetValue();
2764 // If we don't want to resize this window, just move it...
2765 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
2766 (constr
->height
.GetRelationship() != wxAsIs
))
2768 // Calls Layout() recursively. AAAGH. How can we stop that.
2769 // Simply take Layout() out of non-top level OnSizes.
2770 SizerSetSize(x
, y
, w
, h
);
2779 char *windowClass
= this->GetClassInfo()->GetClassName();
2782 if (GetName() == "")
2783 winName
= _("unnamed");
2785 winName
= GetName();
2786 wxDebugMsg(_("Constraint(s) not satisfied for window of type %s, name %s:\n"), (const char *)windowClass
, (const char *)winName
);
2787 if (!constr
->left
.GetDone())
2788 wxDebugMsg(_(" unsatisfied 'left' constraint.\n"));
2789 if (!constr
->right
.GetDone())
2790 wxDebugMsg(_(" unsatisfied 'right' constraint.\n"));
2791 if (!constr
->width
.GetDone())
2792 wxDebugMsg(_(" unsatisfied 'width' constraint.\n"));
2793 if (!constr
->height
.GetDone())
2794 wxDebugMsg(_(" unsatisfied 'height' constraint.\n"));
2795 wxDebugMsg(_("Please check constraints: try adding AsIs() constraints.\n"));
2800 wxNode
*node
= GetChildren()->First();
2803 wxWindow
*win
= (wxWindow
*)node
->Data();
2804 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2805 win
->SetConstraintSizes();
2806 node
= node
->Next();
2811 // This assumes that all sizers are 'on' the same
2812 // window, i.e. the parent of this window.
2813 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
2815 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
2816 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
2820 m_sizerParent
->GetPosition(&xp
, &yp
);
2821 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
2826 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
2830 TransformSizerToActual(&xx
, &yy
);
2831 SetSize(xx
, yy
, w
, h
);
2834 void wxWindow::SizerMove(int x
, int y
)
2838 TransformSizerToActual(&xx
, &yy
);
2842 // Only set the size/position of the constraint (if any)
2843 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
2845 wxLayoutConstraints
*constr
= GetConstraints();
2850 constr
->left
.SetValue(x
);
2851 constr
->left
.SetDone(TRUE
);
2855 constr
->top
.SetValue(y
);
2856 constr
->top
.SetDone(TRUE
);
2860 constr
->width
.SetValue(w
);
2861 constr
->width
.SetDone(TRUE
);
2865 constr
->height
.SetValue(h
);
2866 constr
->height
.SetDone(TRUE
);
2871 void wxWindow::MoveConstraint(int x
, int y
)
2873 wxLayoutConstraints
*constr
= GetConstraints();
2878 constr
->left
.SetValue(x
);
2879 constr
->left
.SetDone(TRUE
);
2883 constr
->top
.SetValue(y
);
2884 constr
->top
.SetDone(TRUE
);
2889 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
2891 wxLayoutConstraints
*constr
= GetConstraints();
2894 *w
= constr
->width
.GetValue();
2895 *h
= constr
->height
.GetValue();
2901 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
2903 wxLayoutConstraints
*constr
= GetConstraints();
2906 *w
= constr
->width
.GetValue();
2907 *h
= constr
->height
.GetValue();
2910 GetClientSize(w
, h
);
2913 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
2915 wxLayoutConstraints
*constr
= GetConstraints();
2918 *x
= constr
->left
.GetValue();
2919 *y
= constr
->top
.GetValue();
2925 bool wxWindow::AcceptsFocus() const
2927 return IsEnabled() && IsShown();
2930 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )