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 #if wxUSE_DRAG_AND_DROP
27 #include "wx/tooltip.h"
29 #include "wx/statusbr.h"
31 #include "wx/settings.h"
38 #include "gdk/gdkprivate.h"
39 #include "gdk/gdkkeysyms.h"
40 #include "wx/gtk/win_gtk.h"
42 //-----------------------------------------------------------------------------
43 // documentation on internals
44 //-----------------------------------------------------------------------------
47 I have been asked several times about writing some documentation about
48 the GTK port of wxWindows, especially its internal structures. Obviously,
49 you cannot understand wxGTK without knowing a little about the GTK, but
50 some more information about what the wxWindow, which is the base class
51 for all other window classes, does seems required as well.
53 What does wxWindow do? It contains the common interface for the following
54 jobs of its descendants:
56 1) Define the rudimentary behaviour common to all window classes, such as
57 resizing, intercepting user input (so as to make it possible to use these
58 events for special purposes in a derived class), window names etc.
60 2) Provide the possibility to contain and manage children, if the derived
61 class is allowed to contain children, which holds true for those window
62 classes which do not display a native GTK widget. To name them, these
63 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
64 work classes are a special case and are handled a bit differently from
65 the rest. The same holds true for the wxNotebook class.
67 3) Provide the possibility to draw into a client area of a window. This,
68 too, only holds true for classes that do not display a native GTK widget
71 4) Provide the entire mechanism for scrolling widgets. This actual inter-
72 face for this is usually in wxScrolledWindow, but the GTK implementation
75 5) A multitude of helper or extra methods for special purposes, such as
76 Drag'n'Drop, managing validators etc.
78 Normally one might expect, that one wxWindows window would always correspond
79 to one GTK widget. Under GTK, there is no such allround widget that has all
80 the functionality. Moreover, the GTK defines a client area as a different
81 widget from the actual widget you are handling. Last but not least some
82 special classes (e.g. wxFrame) handle different categories of widgets and
83 still have the possibility to draw something in the client area.
84 It was therefore required to write a special purpose GTK widget, that would
85 represent a client area in the sense of wxWindows capable to do the jobs
86 2), 3) and 4). I have written this class and it resides in win_gtk.c of
89 All windows must have a widget, with which they interact with other under-
90 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
91 thw wxWindow class has a member variable called m_widget which holds a
92 pointer to this widget. When the window class represents a GTK native widget,
93 this is (in most cases) the only GTK widget the class manages. E.g. the
94 wxStatitText class handles only a GtkLabel widget a pointer to which you
95 can find in m_widget (defined in wxWindow)
97 When the class has a client area for drawing into and for containing children
98 it has to handle the client area widget (of the type GtkMyFixed, defined in
99 win_gtk.c), but there could be any number of widgets, handled by a class
100 The common rule for all windows is only, that the widget that interacts with
101 the rest of GTK must be referenced in m_widget and all other widgets must be
102 children of this widget on the GTK level. The top-most widget, which also
103 represents the client area, must be in the m_wxwindow field and must be of
106 As I said, the window classes that display a GTK native widget only have
107 one widget, so in the case of e.g. the wxButton class m_widget holds a
108 pointer to a GtkButton widget. But windows with client areas (for drawing
109 and children) have a m_widget field that is a pointer to a GtkScrolled-
110 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
111 one is (in the GTK sense) a child of the GtkScrolledWindow.
113 If the m_wxwindow field is set, then all input to this widget is inter-
114 cepted and sent to the wxWindows class. If not, all input to the widget
115 that gets pointed to by m_widget gets intercepted and sent to the class.
119 //-------------------------------------------------------------------------
120 // conditional compilation
121 //-------------------------------------------------------------------------
123 #if (GTK_MINOR_VERSION == 1)
124 #if (GTK_MICRO_VERSION >= 5)
125 #define NEW_GTK_SCROLL_CODE
129 //-----------------------------------------------------------------------------
131 //-----------------------------------------------------------------------------
135 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
136 GdkEvent
*WXUNUSED(event
),
139 printf( "FOCUS NOW AT: " );
146 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
154 char *s
= new char[tmp
.Length()+1];
156 strcpy( s
, WXSTRINGCAST tmp
);
158 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
159 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
164 //-----------------------------------------------------------------------------
166 //-----------------------------------------------------------------------------
168 extern wxList wxPendingDelete
;
169 extern wxList wxTopLevelWindows
;
170 extern bool g_blockEventsOnDrag
;
171 extern bool g_blockEventsOnScroll
;
172 static bool g_capturing
= FALSE
;
173 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
175 // hack: we need something to pass to gtk_menu_popup, so we store the time of
176 // the last click here
177 static guint32 gs_timeLastClick
= 0;
179 //-----------------------------------------------------------------------------
180 // "expose_event" (of m_wxwindow, not of m_widget)
181 //-----------------------------------------------------------------------------
183 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
185 if (!win
->HasVMT()) return;
187 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
189 gdk_event
->area
.width
,
190 gdk_event
->area
.height
);
192 if (gdk_event
->count
> 0) return;
195 printf( "OnExpose from " );
196 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
197 printf( win->GetClassInfo()->GetClassName() );
201 wxPaintEvent
event( win
->GetId() );
202 event
.SetEventObject( win
);
203 win
->GetEventHandler()->ProcessEvent( event
);
205 win
->m_updateRegion
.Clear();
208 //-----------------------------------------------------------------------------
209 // "draw" (of m_wxwindow, not of m_widget)
210 //-----------------------------------------------------------------------------
212 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
214 if (!win
->HasVMT()) return;
216 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
218 wxPaintEvent
event( win
->GetId() );
219 event
.SetEventObject( win
);
220 win
->GetEventHandler()->ProcessEvent( event
);
222 win
->m_updateRegion
.Clear();
225 //-----------------------------------------------------------------------------
226 // "key_press_event" from any window
227 //-----------------------------------------------------------------------------
229 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
231 if (!win
->HasVMT()) return FALSE
;
232 if (g_blockEventsOnDrag
) return FALSE
;
235 printf( "OnKeyPress from " );
236 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
237 printf( win->GetClassInfo()->GetClassName() );
242 switch (gdk_event
->keyval
)
244 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
245 case GDK_Tab
: key_code
= WXK_TAB
; break;
246 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
247 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
248 case GDK_Return
: key_code
= WXK_RETURN
; break;
249 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
250 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
251 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
252 case GDK_Delete
: key_code
= WXK_DELETE
; break;
253 case GDK_Home
: key_code
= WXK_HOME
; break;
254 case GDK_Left
: key_code
= WXK_LEFT
; break;
255 case GDK_Up
: key_code
= WXK_UP
; break;
256 case GDK_Right
: key_code
= WXK_RIGHT
; break;
257 case GDK_Down
: key_code
= WXK_DOWN
; break;
258 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
259 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
260 case GDK_Next
: key_code
= WXK_NEXT
; break;
261 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
262 case GDK_End
: key_code
= WXK_END
; break;
263 case GDK_Begin
: key_code
= WXK_HOME
; break;
264 case GDK_Select
: key_code
= WXK_SELECT
; break;
265 case GDK_Print
: key_code
= WXK_PRINT
; break;
266 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
267 case GDK_Insert
: key_code
= WXK_INSERT
; break;
268 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
269 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
270 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
271 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
272 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
273 case GDK_KP_Up
: key_code
= WXK_UP
; break;
274 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
275 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
276 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
277 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
278 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
279 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
280 case GDK_KP_End
: key_code
= WXK_END
; break;
281 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
282 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
283 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
284 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
285 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
286 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
287 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
288 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
289 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
290 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
291 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
292 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
293 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
294 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
295 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
296 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
297 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
298 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
299 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
300 case GDK_F1
: key_code
= WXK_F1
; break;
301 case GDK_F2
: key_code
= WXK_F2
; break;
302 case GDK_F3
: key_code
= WXK_F3
; break;
303 case GDK_F4
: key_code
= WXK_F4
; break;
304 case GDK_F5
: key_code
= WXK_F5
; break;
305 case GDK_F6
: key_code
= WXK_F6
; break;
306 case GDK_F7
: key_code
= WXK_F7
; break;
307 case GDK_F8
: key_code
= WXK_F8
; break;
308 case GDK_F9
: key_code
= WXK_F9
; break;
309 case GDK_F10
: key_code
= WXK_F10
; break;
310 case GDK_F11
: key_code
= WXK_F11
; break;
311 case GDK_F12
: key_code
= WXK_F12
; break;
314 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
315 key_code
= gdk_event
->keyval
;
319 if (!key_code
) return FALSE
;
321 wxKeyEvent
event( wxEVT_KEY_DOWN
);
322 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
323 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
324 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
325 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
326 event
.m_keyCode
= key_code
;
329 event
.SetEventObject( win
);
331 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
335 wxWindow
*ancestor
= win
;
338 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
341 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
342 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
345 ancestor
= ancestor
->GetParent();
349 // win is a control: tab can be propagated up
350 if ((!ret
) && (gdk_event
->keyval
== GDK_Tab
) && ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
352 wxNavigationKeyEvent new_event
;
353 new_event
.SetDirection( !(gdk_event
->state
& GDK_SHIFT_MASK
) );
354 new_event
.SetWindowChange( FALSE
);
355 new_event
.SetCurrentFocus( win
);
356 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
360 // win is a panel: up can be propagated to the panel
361 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
362 (gdk_event->keyval == GDK_Up))
364 win->m_parent->SetFocus();
368 // win is a panel: left/right can be propagated to the panel
369 if ((!ret) && (win->m_wxwindow) &&
370 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
371 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
373 wxNavigationKeyEvent new_event;
374 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
375 new_event.SetCurrentFocus( win );
376 ret = win->GetEventHandler()->ProcessEvent( new_event );
382 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
388 //-----------------------------------------------------------------------------
389 // "key_release_event" from any window
390 //-----------------------------------------------------------------------------
392 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
394 if (!win
->HasVMT()) return FALSE
;
395 if (g_blockEventsOnDrag
) return FALSE
;
398 printf( "OnKeyRelease from " );
399 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
400 printf( win->GetClassInfo()->GetClassName() );
405 switch (gdk_event
->keyval
)
407 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
408 case GDK_Tab
: key_code
= WXK_TAB
; break;
409 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
410 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
411 case GDK_Return
: key_code
= WXK_RETURN
; break;
412 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
413 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
414 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
415 case GDK_Delete
: key_code
= WXK_DELETE
; break;
416 case GDK_Home
: key_code
= WXK_HOME
; break;
417 case GDK_Left
: key_code
= WXK_LEFT
; break;
418 case GDK_Up
: key_code
= WXK_UP
; break;
419 case GDK_Right
: key_code
= WXK_RIGHT
; break;
420 case GDK_Down
: key_code
= WXK_DOWN
; break;
421 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
422 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
423 case GDK_Next
: key_code
= WXK_NEXT
; break;
424 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
425 case GDK_End
: key_code
= WXK_END
; break;
426 case GDK_Begin
: key_code
= WXK_HOME
; break;
427 case GDK_Select
: key_code
= WXK_SELECT
; break;
428 case GDK_Print
: key_code
= WXK_PRINT
; break;
429 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
430 case GDK_Insert
: key_code
= WXK_INSERT
; break;
431 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
432 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
433 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
434 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
435 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
436 case GDK_KP_Up
: key_code
= WXK_UP
; break;
437 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
438 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
439 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
440 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
441 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
442 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
443 case GDK_KP_End
: key_code
= WXK_END
; break;
444 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
445 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
446 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
447 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
448 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
449 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
450 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
451 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
452 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
453 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
454 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
455 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
456 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
457 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
458 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
459 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
460 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
461 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
462 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
463 case GDK_F1
: key_code
= WXK_F1
; break;
464 case GDK_F2
: key_code
= WXK_F2
; break;
465 case GDK_F3
: key_code
= WXK_F3
; break;
466 case GDK_F4
: key_code
= WXK_F4
; break;
467 case GDK_F5
: key_code
= WXK_F5
; break;
468 case GDK_F6
: key_code
= WXK_F6
; break;
469 case GDK_F7
: key_code
= WXK_F7
; break;
470 case GDK_F8
: key_code
= WXK_F8
; break;
471 case GDK_F9
: key_code
= WXK_F9
; break;
472 case GDK_F10
: key_code
= WXK_F10
; break;
473 case GDK_F11
: key_code
= WXK_F11
; break;
474 case GDK_F12
: key_code
= WXK_F12
; break;
477 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
478 key_code
= gdk_event
->keyval
;
482 if (!key_code
) return FALSE
;
484 wxKeyEvent
event( wxEVT_KEY_UP
);
485 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
486 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
487 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
488 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
489 event
.m_keyCode
= key_code
;
492 event
.SetEventObject( win
);
494 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
498 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
504 //-----------------------------------------------------------------------------
505 // "button_press_event"
506 //-----------------------------------------------------------------------------
508 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
510 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
512 if (g_blockEventsOnDrag
) return TRUE
;
513 if (g_blockEventsOnScroll
) return TRUE
;
517 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
519 gtk_widget_grab_focus (win
->m_wxwindow
);
522 printf( "GrabFocus from " );
523 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
524 printf( win->GetClassInfo()->GetClassName() );
531 if (!win
->HasVMT()) return TRUE
;
534 printf( "OnButtonPress from " );
535 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
536 printf( win->GetClassInfo()->GetClassName() );
540 wxEventType event_type
= wxEVT_LEFT_DOWN
;
542 if (gdk_event
->button
== 1)
544 switch (gdk_event
->type
)
546 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
547 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
551 else if (gdk_event
->button
== 2)
553 switch (gdk_event
->type
)
555 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
556 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
560 else if (gdk_event
->button
== 3)
562 switch (gdk_event
->type
)
564 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
565 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
570 wxMouseEvent
event( event_type
);
571 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
572 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
573 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
574 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
575 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
576 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
577 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
579 event
.m_x
= (long)gdk_event
->x
;
580 event
.m_y
= (long)gdk_event
->y
;
582 // Some control don't have their own X window and thus cannot get
587 wxNode
*node
= win
->GetChildren().First();
590 wxWindow
*child
= (wxWindow
*)node
->Data();
592 if (child
->m_isStaticBox
)
594 // wxStaticBox is transparent in the box itself
597 int xx1
= child
->m_x
;
598 int yy1
= child
->m_y
;
599 int xx2
= child
->m_x
+ child
->m_width
;
600 int yy2
= child
->m_x
+ child
->m_height
;
603 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
605 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
607 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
609 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
612 event
.m_x
-= child
->m_x
;
613 event
.m_y
-= child
->m_y
;
620 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
621 (child
->m_x
<= event
.m_x
) &&
622 (child
->m_y
<= event
.m_y
) &&
623 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
624 (child
->m_y
+child
->m_height
>= event
.m_y
))
627 event
.m_x
-= child
->m_x
;
628 event
.m_y
-= child
->m_y
;
636 wxPoint
pt(win
->GetClientAreaOrigin());
640 event
.SetEventObject( win
);
642 gs_timeLastClick
= gdk_event
->time
;
644 if (win
->GetEventHandler()->ProcessEvent( event
))
645 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
650 //-----------------------------------------------------------------------------
651 // "button_release_event"
652 //-----------------------------------------------------------------------------
654 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
656 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
658 if (g_blockEventsOnDrag
) return TRUE
;
659 if (g_blockEventsOnScroll
) return TRUE
;
661 if (!win
->HasVMT()) return TRUE
;
664 printf( "OnButtonRelease from " );
665 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
666 printf( win->GetClassInfo()->GetClassName() );
670 wxEventType event_type
= wxEVT_NULL
;
672 switch (gdk_event
->button
)
674 case 1: event_type
= wxEVT_LEFT_UP
; break;
675 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
676 case 3: event_type
= wxEVT_RIGHT_UP
; break;
679 wxMouseEvent
event( event_type
);
680 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
681 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
682 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
683 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
684 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
685 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
686 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
687 event
.m_x
= (long)gdk_event
->x
;
688 event
.m_y
= (long)gdk_event
->y
;
690 // Some control don't have their own X window and thus cannot get
695 wxNode
*node
= win
->GetChildren().First();
698 wxWindow
*child
= (wxWindow
*)node
->Data();
700 if (child
->m_isStaticBox
)
702 // wxStaticBox is transparent in the box itself
705 int xx1
= child
->m_x
;
706 int yy1
= child
->m_y
;
707 int xx2
= child
->m_x
+ child
->m_width
;
708 int yy2
= child
->m_x
+ child
->m_height
;
711 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
713 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
715 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
717 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
720 event
.m_x
-= child
->m_x
;
721 event
.m_y
-= child
->m_y
;
728 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
729 (child
->m_x
<= event
.m_x
) &&
730 (child
->m_y
<= event
.m_y
) &&
731 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
732 (child
->m_y
+child
->m_height
>= event
.m_y
))
735 event
.m_x
-= child
->m_x
;
736 event
.m_y
-= child
->m_y
;
744 wxPoint
pt(win
->GetClientAreaOrigin());
748 event
.SetEventObject( win
);
750 if (win
->GetEventHandler()->ProcessEvent( event
))
751 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
756 //-----------------------------------------------------------------------------
757 // "motion_notify_event"
758 //-----------------------------------------------------------------------------
760 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
762 if (gdk_event
->is_hint
)
766 GdkModifierType state
;
767 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
770 gdk_event
->state
= state
;
773 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
775 if (g_blockEventsOnDrag
) return TRUE
;
776 if (g_blockEventsOnScroll
) return TRUE
;
778 if (!win
->HasVMT()) return TRUE
;
781 printf( "OnMotion from " );
782 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
783 printf( win->GetClassInfo()->GetClassName() );
787 wxMouseEvent
event( wxEVT_MOTION
);
788 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
789 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
790 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
791 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
792 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
793 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
794 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
796 event
.m_x
= (long)gdk_event
->x
;
797 event
.m_y
= (long)gdk_event
->y
;
799 // Some control don't have their own X window and thus cannot get
804 wxNode
*node
= win
->GetChildren().First();
807 wxWindow
*child
= (wxWindow
*)node
->Data();
809 if (child
->m_isStaticBox
)
811 // wxStaticBox is transparent in the box itself
814 int xx1
= child
->m_x
;
815 int yy1
= child
->m_y
;
816 int xx2
= child
->m_x
+ child
->m_width
;
817 int yy2
= child
->m_x
+ child
->m_height
;
820 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
822 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
824 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
826 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
829 event
.m_x
-= child
->m_x
;
830 event
.m_y
-= child
->m_y
;
837 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
838 (child
->m_x
<= event
.m_x
) &&
839 (child
->m_y
<= event
.m_y
) &&
840 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
841 (child
->m_y
+child
->m_height
>= event
.m_y
))
844 event
.m_x
-= child
->m_x
;
845 event
.m_y
-= child
->m_y
;
853 wxPoint
pt(win
->GetClientAreaOrigin());
857 event
.SetEventObject( win
);
859 if (win
->GetEventHandler()->ProcessEvent( event
))
860 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
865 //-----------------------------------------------------------------------------
867 //-----------------------------------------------------------------------------
869 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
871 if (g_blockEventsOnDrag
) return TRUE
;
877 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
879 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
881 printf( "SetFocus flag from " );
882 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
883 printf( win->GetClassInfo()->GetClassName() );
889 if (!win
->HasVMT()) return TRUE
;
892 printf( "OnSetFocus from " );
893 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
894 printf( win->GetClassInfo()->GetClassName() );
896 printf( WXSTRINGCAST win->GetLabel() );
900 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
901 event
.SetEventObject( win
);
903 if (win
->GetEventHandler()->ProcessEvent( event
))
904 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
909 //-----------------------------------------------------------------------------
911 //-----------------------------------------------------------------------------
913 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
915 if (g_blockEventsOnDrag
) return TRUE
;
918 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
919 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
922 if (!win
->HasVMT()) return TRUE
;
925 printf( "OnKillFocus from " );
926 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
927 printf( win->GetClassInfo()->GetClassName() );
931 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
932 event
.SetEventObject( win
);
934 if (win
->GetEventHandler()->ProcessEvent( event
))
935 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
940 //-----------------------------------------------------------------------------
941 // "enter_notify_event"
942 //-----------------------------------------------------------------------------
944 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
946 if (g_blockEventsOnDrag
) return TRUE
;
948 if ((widget
->window
) && (win
->m_cursor
))
949 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
951 if (widget
->window
!= gdk_event
->window
) return TRUE
;
953 if (!win
->HasVMT()) return TRUE
;
956 printf( "OnEnter from " );
957 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
958 printf( win->GetClassInfo()->GetClassName() );
962 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
963 event
.SetEventObject( win
);
967 GdkModifierType state
= (GdkModifierType
)0;
969 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
971 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
972 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
973 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
974 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
975 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
976 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
977 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
982 wxPoint
pt(win
->GetClientAreaOrigin());
986 if (win
->GetEventHandler()->ProcessEvent( event
))
987 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
992 //-----------------------------------------------------------------------------
993 // "leave_notify_event"
994 //-----------------------------------------------------------------------------
996 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
998 if (g_blockEventsOnDrag
) return TRUE
;
1000 if ((widget
->window
) && (win
->m_cursor
))
1001 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1003 if (widget
->window
!= gdk_event
->window
) return TRUE
;
1005 if (!win
->HasVMT()) return TRUE
;
1008 printf( "OnLeave from " );
1009 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1010 printf( win->GetClassInfo()->GetClassName() );
1014 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1015 event
.SetEventObject( win
);
1019 GdkModifierType state
= (GdkModifierType
)0;
1021 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1023 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1024 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1025 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1026 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1027 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1028 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1029 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1031 event
.m_x
= (long)x
;
1032 event
.m_y
= (long)y
;
1034 wxPoint
pt(win
->GetClientAreaOrigin());
1038 if (win
->GetEventHandler()->ProcessEvent( event
))
1039 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1044 //-----------------------------------------------------------------------------
1045 // "value_changed" from m_vAdjust
1046 //-----------------------------------------------------------------------------
1048 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1050 if (g_blockEventsOnDrag
) return;
1053 printf( "OnVScroll from " );
1054 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1055 printf( win->GetClassInfo()->GetClassName() );
1059 if (!win
->HasVMT()) return;
1061 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1062 if (fabs(diff
) < 0.2) return;
1064 wxEventType command
= wxEVT_NULL
;
1066 float line_step
= win
->m_vAdjust
->step_increment
;
1067 float page_step
= win
->m_vAdjust
->page_increment
;
1069 if (win
->m_isScrolling
)
1071 command
= wxEVT_SCROLL_THUMBTRACK
;
1075 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1076 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1077 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1078 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1079 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1080 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1081 else command
= wxEVT_SCROLL_THUMBTRACK
;
1084 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1086 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1087 event
.SetEventObject( win
);
1088 win
->GetEventHandler()->ProcessEvent( event
);
1091 //-----------------------------------------------------------------------------
1092 // "value_changed" from m_hAdjust
1093 //-----------------------------------------------------------------------------
1095 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1097 if (g_blockEventsOnDrag
) return;
1100 printf( "OnHScroll from " );
1101 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1102 printf( win->GetClassInfo()->GetClassName() );
1106 if (!win
->HasVMT()) return;
1108 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1109 if (fabs(diff
) < 0.2) return;
1111 wxEventType command
= wxEVT_NULL
;
1113 float line_step
= win
->m_hAdjust
->step_increment
;
1114 float page_step
= win
->m_hAdjust
->page_increment
;
1116 if (win
->m_isScrolling
)
1118 command
= wxEVT_SCROLL_THUMBTRACK
;
1122 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1123 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1124 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1125 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1126 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1127 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1128 else command
= wxEVT_SCROLL_THUMBTRACK
;
1131 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1133 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1134 event
.SetEventObject( win
);
1135 win
->GetEventHandler()->ProcessEvent( event
);
1138 //-----------------------------------------------------------------------------
1139 // "changed" from m_vAdjust
1140 //-----------------------------------------------------------------------------
1142 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1144 if (g_blockEventsOnDrag
) return;
1147 printf( "OnVScroll change from " );
1148 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1149 printf( win->GetClassInfo()->GetClassName() );
1153 if (!win
->HasVMT()) return;
1155 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1156 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1158 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1159 event
.SetEventObject( win
);
1160 win
->GetEventHandler()->ProcessEvent( event
);
1163 //-----------------------------------------------------------------------------
1164 // "changed" from m_hAdjust
1165 //-----------------------------------------------------------------------------
1167 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1169 if (g_blockEventsOnDrag
) return;
1172 printf( "OnHScroll change from " );
1173 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1174 printf( win->GetClassInfo()->GetClassName() );
1178 if (!win
->HasVMT()) return;
1180 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1181 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1183 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1184 event
.SetEventObject( win
);
1185 win
->GetEventHandler()->ProcessEvent( event
);
1188 //-----------------------------------------------------------------------------
1189 // "button_press_event" from scrollbar
1190 //-----------------------------------------------------------------------------
1192 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1193 GdkEventButton
*WXUNUSED(gdk_event
),
1196 // don't test here as we can release the mouse while being over
1197 // a different window then the slider
1199 // if (gdk_event->window != widget->slider) return FALSE;
1201 win
->m_isScrolling
= TRUE
;
1202 g_blockEventsOnScroll
= TRUE
;
1207 //-----------------------------------------------------------------------------
1208 // "button_release_event" from scrollbar
1209 //-----------------------------------------------------------------------------
1211 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1212 GdkEventButton
*WXUNUSED(gdk_event
),
1216 // don't test here as we can release the mouse while being over
1217 // a different window then the slider
1219 // if (gdk_event->window != widget->slider) return FALSE;
1221 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1223 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1224 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1226 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1228 win
->m_isScrolling
= FALSE
;
1229 g_blockEventsOnScroll
= FALSE
;
1234 //-----------------------------------------------------------------------------
1235 // InsertChild for wxWindow.
1236 //-----------------------------------------------------------------------------
1238 /* Callback for wxWindow. This very strange beast has to be used because
1239 * C++ has no virtual methods in a constructor. We have to emulate a
1240 * virtual function here as wxNotebook requires a different way to insert
1241 * a child in it. I had opted for creating a wxNotebookPage window class
1242 * which would have made this superfluous (such in the MDI window system),
1243 * but no-one was listening to me... */
1245 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1247 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1248 GTK_WIDGET(child
->m_widget
),
1252 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1256 if (wxIS_KIND_OF(parent
,wxFrame
))
1258 parent
->m_sizeSet
= FALSE
;
1261 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1263 /* we now allow a window to get the focus as long as it
1264 doesn't have any children. */
1265 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1269 //-----------------------------------------------------------------------------
1271 //-----------------------------------------------------------------------------
1273 wxWindow
* wxGetActiveWindow()
1275 return g_focusWindow
;
1278 //-----------------------------------------------------------------------------
1280 //-----------------------------------------------------------------------------
1282 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1284 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1285 EVT_SIZE(wxWindow::OnSize
)
1286 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1287 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1288 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1291 wxWindow::wxWindow()
1293 m_widget
= (GtkWidget
*) NULL
;
1294 m_wxwindow
= (GtkWidget
*) NULL
;
1295 m_parent
= (wxWindow
*) NULL
;
1296 m_children
.DeleteContents( FALSE
);
1309 m_eventHandler
= this;
1310 m_windowValidator
= (wxValidator
*) NULL
;
1314 m_cursor
= (wxCursor
*) NULL
;
1315 m_font
= *wxSWISS_FONT
;
1317 m_windowName
= "noname";
1319 m_constraints
= (wxLayoutConstraints
*) NULL
;
1320 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1321 m_windowSizer
= (wxSizer
*) NULL
;
1322 m_sizerParent
= (wxWindow
*) NULL
;
1323 m_autoLayout
= FALSE
;
1327 m_needParent
= TRUE
;
1329 m_hasScrolling
= FALSE
;
1330 m_isScrolling
= FALSE
;
1331 m_hAdjust
= (GtkAdjustment
*) NULL
;
1332 m_vAdjust
= (GtkAdjustment
*) NULL
;
1333 m_oldHorizontalPos
= 0.0;
1334 m_oldVerticalPos
= 0.0;
1339 #if wxUSE_DRAG_AND_DROP
1340 m_dropTarget
= (wxDropTarget
*) NULL
;
1343 m_scrollGC
= (GdkGC
*) NULL
;
1344 m_widgetStyle
= (GtkStyle
*) NULL
;
1346 m_insertCallback
= wxInsertChildInWindow
;
1348 m_clientObject
= (wxClientData
*) NULL
;
1349 m_clientData
= NULL
;
1351 m_isStaticBox
= FALSE
;
1352 m_acceptsFocus
= FALSE
;
1355 m_toolTip
= (wxToolTip
*) NULL
;
1356 #endif // wxUSE_TOOLTIPS
1359 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1360 const wxPoint
&pos
, const wxSize
&size
,
1361 long style
, const wxString
&name
)
1363 m_insertCallback
= wxInsertChildInWindow
;
1364 Create( parent
, id
, pos
, size
, style
, name
);
1367 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1368 const wxPoint
&pos
, const wxSize
&size
,
1369 long style
, const wxString
&name
)
1373 m_needParent
= TRUE
;
1375 PreCreation( parent
, id
, pos
, size
, style
, name
);
1377 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1378 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1381 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1384 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1387 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1388 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1391 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1392 scroll_class
->scrollbar_spacing
= 0;
1394 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1396 m_oldHorizontalPos
= 0.0;
1397 m_oldVerticalPos
= 0.0;
1399 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1400 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1402 m_wxwindow
= gtk_myfixed_new();
1405 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1408 #ifdef NEW_GTK_SCROLL_CODE
1409 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1410 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1412 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1413 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1417 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1420 if (m_windowStyle
& wxRAISED_BORDER
)
1422 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1424 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1426 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1430 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1433 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1435 /* we now allow a window to get the focus as long as it
1436 doesn't have any children. */
1437 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1438 m_acceptsFocus
= FALSE
;
1442 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1443 m_acceptsFocus
= TRUE
;
1446 // shut the viewport up
1447 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1448 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1450 // I _really_ don't want scrollbars in the beginning
1451 m_vAdjust
->lower
= 0.0;
1452 m_vAdjust
->upper
= 1.0;
1453 m_vAdjust
->value
= 0.0;
1454 m_vAdjust
->step_increment
= 1.0;
1455 m_vAdjust
->page_increment
= 1.0;
1456 m_vAdjust
->page_size
= 5.0;
1457 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1458 m_hAdjust
->lower
= 0.0;
1459 m_hAdjust
->upper
= 1.0;
1460 m_hAdjust
->value
= 0.0;
1461 m_hAdjust
->step_increment
= 1.0;
1462 m_hAdjust
->page_increment
= 1.0;
1463 m_hAdjust
->page_size
= 5.0;
1464 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1466 // these handlers block mouse events to any window during scrolling
1467 // such as motion events and prevent GTK and wxWindows from fighting
1468 // over where the slider should be
1470 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1471 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1473 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1474 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1476 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1477 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1479 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1480 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1482 // these handers het notified when screen updates are required either when
1483 // scrolling or when the window size (and therefore scrollbar configuration)
1486 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1487 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1488 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1489 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1491 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1492 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1493 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1494 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1496 gtk_widget_show( m_wxwindow
);
1498 if (m_parent
) m_parent
->AddChild( this );
1500 (m_parent
->m_insertCallback
)( m_parent
, this );
1509 wxWindow::~wxWindow()
1513 #if wxUSE_DRAG_AND_DROP
1514 wxDELETE(m_dropTarget
);
1518 wxDELETE(m_toolTip
);
1519 #endif // wxUSE_TOOLTIPS
1521 if (m_parent
) m_parent
->RemoveChild( this );
1522 if (m_widget
) Show( FALSE
);
1526 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1528 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1530 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1532 if (m_widget
) gtk_widget_destroy( m_widget
);
1534 if (m_cursor
) delete m_cursor
;
1536 DeleteRelatedConstraints();
1539 // This removes any dangling pointers to this window
1540 // in other windows' constraintsInvolvedIn lists.
1541 UnsetConstraints(m_constraints
);
1542 delete m_constraints
;
1543 m_constraints
= (wxLayoutConstraints
*) NULL
;
1547 delete m_windowSizer
;
1548 m_windowSizer
= (wxSizer
*) NULL
;
1550 // If this is a child of a sizer, remove self from parent
1551 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1553 // Just in case the window has been Closed, but
1554 // we're then deleting immediately: don't leave
1555 // dangling pointers.
1556 wxPendingDelete
.DeleteObject(this);
1558 // Just in case we've loaded a top-level window via
1559 // wxWindow::LoadNativeDialog but we weren't a dialog
1561 wxTopLevelWindows
.DeleteObject(this);
1563 if (m_windowValidator
) delete m_windowValidator
;
1565 if (m_clientObject
) delete m_clientObject
;
1568 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1569 const wxPoint
&pos
, const wxSize
&size
,
1570 long style
, const wxString
&name
)
1572 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1574 m_widget
= (GtkWidget
*) NULL
;
1575 m_wxwindow
= (GtkWidget
*) NULL
;
1578 m_children
.DeleteContents( FALSE
);
1581 if (m_width
== -1) m_width
= 20;
1583 if (m_height
== -1) m_height
= 20;
1588 if (!m_needParent
) // some reasonable defaults
1592 m_x
= (gdk_screen_width () - m_width
) / 2;
1593 if (m_x
< 10) m_x
= 10;
1597 m_y
= (gdk_screen_height () - m_height
) / 2;
1598 if (m_y
< 10) m_y
= 10;
1609 m_eventHandler
= this;
1611 m_windowId
= id
== -1 ? wxNewId() : id
;
1615 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1616 m_font
= *wxSWISS_FONT
;
1617 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1618 m_foregroundColour
= *wxBLACK
;
1619 m_windowStyle
= style
;
1620 m_windowName
= name
;
1622 m_constraints
= (wxLayoutConstraints
*) NULL
;
1623 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1624 m_windowSizer
= (wxSizer
*) NULL
;
1625 m_sizerParent
= (wxWindow
*) NULL
;
1626 m_autoLayout
= FALSE
;
1628 m_hasScrolling
= FALSE
;
1629 m_isScrolling
= FALSE
;
1630 m_hAdjust
= (GtkAdjustment
*) NULL
;
1631 m_vAdjust
= (GtkAdjustment
*) NULL
;
1632 m_oldHorizontalPos
= 0.0;
1633 m_oldVerticalPos
= 0.0;
1638 #if wxUSE_DRAG_AND_DROP
1639 m_dropTarget
= (wxDropTarget
*) NULL
;
1642 m_windowValidator
= (wxValidator
*) NULL
;
1643 m_scrollGC
= (GdkGC
*) NULL
;
1644 m_widgetStyle
= (GtkStyle
*) NULL
;
1646 m_clientObject
= (wxClientData
*)NULL
;
1647 m_clientData
= NULL
;
1649 m_isStaticBox
= FALSE
;
1652 m_toolTip
= (wxToolTip
*) NULL
;
1653 #endif // wxUSE_TOOLTIPS
1656 void wxWindow::PostCreation()
1660 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1661 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1663 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1664 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1667 ConnectWidget( GetConnectWidget() );
1669 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1671 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1673 SetCursor( *wxSTANDARD_CURSOR
);
1678 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1680 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1681 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1683 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1684 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1686 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1687 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1689 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1690 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1692 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1693 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1695 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1696 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1698 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1699 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1701 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1702 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1704 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1705 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1708 bool wxWindow::HasVMT()
1713 bool wxWindow::Close( bool force
)
1715 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1717 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1718 event
.SetEventObject(this);
1719 event
.SetCanVeto(!force
);
1721 // return FALSE if window wasn't closed because the application vetoed the
1723 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1726 bool wxWindow::Destroy()
1728 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1735 bool wxWindow::DestroyChildren()
1738 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1741 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1744 if (m_children
.Member(child
)) delete node
;
1750 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1752 // are we to set fonts here ?
1755 wxPoint
wxWindow::GetClientAreaOrigin() const
1757 return wxPoint(0,0);
1760 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1762 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1764 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1770 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1772 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1773 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1775 if (m_resizing
) return; // I don't like recursions
1778 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1780 // don't set the size for children of wxNotebook, just take the values.
1788 int old_width
= m_width
;
1789 int old_height
= m_height
;
1791 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1793 if (x
!= -1) m_x
= x
;
1794 if (y
!= -1) m_y
= y
;
1795 if (width
!= -1) m_width
= width
;
1796 if (height
!= -1) m_height
= height
;
1806 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1808 if (width
== -1) m_width
= 80;
1811 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1813 if (height
== -1) m_height
= 26;
1816 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1817 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1818 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1819 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1821 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1822 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1824 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1825 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1830 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1831 event
.SetEventObject( this );
1832 GetEventHandler()->ProcessEvent( event
);
1837 void wxWindow::OnInternalIdle()
1842 void wxWindow::SetSize( int width
, int height
)
1844 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1847 void wxWindow::Move( int x
, int y
)
1849 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1852 void wxWindow::GetSize( int *width
, int *height
) const
1854 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1856 if (width
) (*width
) = m_width
;
1857 if (height
) (*height
) = m_height
;
1860 void wxWindow::SetClientSize( int width
, int height
)
1862 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1866 SetSize( width
, height
);
1873 if (!m_hasScrolling
)
1875 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1877 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1878 (m_windowStyle
& wxSUNKEN_BORDER
))
1880 dw
+= 2 * window_class
->xthickness
;
1881 dh
+= 2 * window_class
->ythickness
;
1886 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1887 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1889 #ifdef NEW_GTK_SCROLL_CODE
1890 GtkWidget
*viewport
= scroll_window
->child
;
1892 GtkWidget
*viewport
= scroll_window
->viewport
;
1895 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1897 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1898 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1900 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1901 (m_windowStyle
& wxSUNKEN_BORDER
))
1903 dw
+= 2 * viewport_class
->xthickness
;
1904 dh
+= 2 * viewport_class
->ythickness
;
1907 if (scroll_window
->vscrollbar_visible
)
1909 dw
+= vscrollbar
->allocation
.width
;
1910 dw
+= scroll_class
->scrollbar_spacing
;
1913 if (scroll_window
->hscrollbar_visible
)
1915 dh
+= hscrollbar
->allocation
.height
;
1916 dw
+= scroll_class
->scrollbar_spacing
;
1920 SetSize( width
+dw
, height
+dh
);
1924 void wxWindow::GetClientSize( int *width
, int *height
) const
1926 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1930 if (width
) (*width
) = m_width
;
1931 if (height
) (*height
) = m_height
;
1938 if (!m_hasScrolling
)
1940 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1942 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1943 (m_windowStyle
& wxSUNKEN_BORDER
))
1945 dw
+= 2 * window_class
->xthickness
;
1946 dh
+= 2 * window_class
->ythickness
;
1951 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1952 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1954 #ifdef NEW_GTK_SCROLL_CODE
1955 GtkWidget
*viewport
= scroll_window
->child
;
1957 GtkWidget
*viewport
= scroll_window
->viewport
;
1960 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1962 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1963 (m_windowStyle
& wxSUNKEN_BORDER
))
1965 dw
+= 2 * viewport_class
->xthickness
;
1966 dh
+= 2 * viewport_class
->ythickness
;
1969 if (scroll_window
->vscrollbar_visible
)
1971 // dw += vscrollbar->allocation.width;
1972 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1973 dw
+= scroll_class
->scrollbar_spacing
;
1976 if (scroll_window
->hscrollbar_visible
)
1978 // dh += hscrollbar->allocation.height;
1980 dh
+= scroll_class
->scrollbar_spacing
;
1984 if (width
) (*width
) = m_width
- dw
;
1985 if (height
) (*height
) = m_height
- dh
;
1989 void wxWindow::GetPosition( int *x
, int *y
) const
1991 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1997 void wxWindow::ClientToScreen( int *x
, int *y
)
1999 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2001 GdkWindow
*source
= (GdkWindow
*) NULL
;
2003 source
= m_wxwindow
->window
;
2005 source
= m_widget
->window
;
2009 gdk_window_get_origin( source
, &org_x
, &org_y
);
2013 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2015 org_x
+= m_widget
->allocation
.x
;
2016 org_y
+= m_widget
->allocation
.y
;
2020 wxPoint
pt(GetClientAreaOrigin());
2028 void wxWindow::ScreenToClient( int *x
, int *y
)
2030 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2032 GdkWindow
*source
= (GdkWindow
*) NULL
;
2034 source
= m_wxwindow
->window
;
2036 source
= m_widget
->window
;
2040 gdk_window_get_origin( source
, &org_x
, &org_y
);
2044 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2046 org_x
+= m_widget
->allocation
.x
;
2047 org_y
+= m_widget
->allocation
.y
;
2051 wxPoint
pt(GetClientAreaOrigin());
2059 void wxWindow::Centre( int direction
)
2061 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2070 m_parent
->GetSize( &p_w
, &p_h
);
2071 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2072 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2076 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2077 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2083 void wxWindow::Fit()
2085 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2089 wxNode
*node
= m_children
.First();
2092 wxWindow
*win
= (wxWindow
*)node
->Data();
2094 win
->GetPosition(&wx
, &wy
);
2095 win
->GetSize(&ww
, &wh
);
2096 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2097 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2099 node
= node
->Next();
2102 SetClientSize(maxX
+ 7, maxY
+ 14);
2105 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2107 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2115 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2117 // if (GetAutoLayout()) Layout();
2120 bool wxWindow::Show( bool show
)
2122 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2125 gtk_widget_show( m_widget
);
2127 gtk_widget_hide( m_widget
);
2134 void wxWindow::Enable( bool enable
)
2136 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2138 m_isEnabled
= enable
;
2140 gtk_widget_set_sensitive( m_widget
, enable
);
2141 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2144 int wxWindow::GetCharHeight() const
2146 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2148 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2150 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2152 return font
->ascent
+ font
->descent
;
2155 int wxWindow::GetCharWidth() const
2157 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2159 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2161 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2163 return gdk_string_width( font
, "H" );
2166 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2167 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2169 wxFont fontToUse
= m_font
;
2170 if (theFont
) fontToUse
= *theFont
;
2172 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2174 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2175 if (x
) (*x
) = gdk_string_width( font
, string
);
2176 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2177 if (descent
) (*descent
) = font
->descent
;
2178 if (externalLeading
) (*externalLeading
) = 0; // ??
2181 void wxWindow::MakeModal( bool modal
)
2185 // Disable all other windows
2186 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2188 wxNode
*node
= wxTopLevelWindows
.First();
2191 wxWindow
*win
= (wxWindow
*)node
->Data();
2192 if (win
!= this) win
->Enable(!modal
);
2194 node
= node
->Next();
2199 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2201 event
.SetEventType( wxEVT_CHAR
);
2203 if (!GetEventHandler()->ProcessEvent( event
))
2209 void wxWindow::SetFocus()
2211 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2213 GtkWidget
*connect_widget
= GetConnectWidget();
2216 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2218 gtk_widget_grab_focus (connect_widget
);
2220 else if (GTK_IS_CONTAINER(connect_widget
))
2222 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2230 wxWindow
*wxWindow::FindFocus()
2232 return g_focusWindow
;
2235 bool wxWindow::AcceptsFocus() const
2237 return IsEnabled() && IsShown() && m_acceptsFocus
;
2240 void wxWindow::AddChild( wxWindow
*child
)
2242 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2243 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2245 m_children
.Append( child
);
2248 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2250 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2252 wxWindow
*oldParent
= GetParent();
2254 if (oldParent
) oldParent
->RemoveChild( this );
2256 gtk_widget_unparent( m_widget
);
2260 newParent
->AddChild( this );
2261 (newParent
->m_insertCallback
)( newParent
, this );
2267 void wxWindow::RemoveChild( wxWindow
*child
)
2269 m_children
.DeleteObject( child
);
2270 child
->m_parent
= (wxWindow
*) NULL
;
2273 void wxWindow::SetReturnCode( int retCode
)
2275 m_retCode
= retCode
;
2278 int wxWindow::GetReturnCode()
2283 void wxWindow::Raise()
2285 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2287 if (m_widget
) gdk_window_raise( m_widget
->window
);
2290 void wxWindow::Lower()
2292 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2294 if (m_widget
) gdk_window_lower( m_widget
->window
);
2297 wxEvtHandler
*wxWindow::GetEventHandler() const
2299 return m_eventHandler
;
2302 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2304 m_eventHandler
= handler
;
2307 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2309 handler
->SetNextHandler(GetEventHandler());
2310 SetEventHandler(handler
);
2313 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2315 if (GetEventHandler())
2317 wxEvtHandler
*handlerA
= GetEventHandler();
2318 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2319 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2320 SetEventHandler(handlerB
);
2324 return (wxEvtHandler
*) NULL
;
2330 return (wxEvtHandler
*) NULL
;
2333 wxValidator
*wxWindow::GetValidator()
2335 return m_windowValidator
;
2338 void wxWindow::SetValidator( const wxValidator
& validator
)
2340 if (m_windowValidator
) delete m_windowValidator
;
2341 m_windowValidator
= validator
.Clone();
2342 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2345 void wxWindow::SetClientObject( wxClientData
*data
)
2347 if (m_clientObject
) delete m_clientObject
;
2348 m_clientObject
= data
;
2351 wxClientData
*wxWindow::GetClientObject()
2353 return m_clientObject
;
2356 void wxWindow::SetClientData( void *data
)
2358 m_clientData
= data
;
2361 void *wxWindow::GetClientData()
2363 return m_clientData
;
2366 bool wxWindow::IsBeingDeleted()
2371 void wxWindow::SetId( wxWindowID id
)
2376 wxWindowID
wxWindow::GetId() const
2381 void wxWindow::SetCursor( const wxCursor
&cursor
)
2383 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2387 if (cursor
== *m_cursor
) return;
2392 *m_cursor
= *wxSTANDARD_CURSOR
;
2395 if ((m_widget
) && (m_widget
->window
))
2396 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2398 if ((m_wxwindow
) && (m_wxwindow
->window
))
2399 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2402 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2407 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2409 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2411 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2415 gdk_window_clear_area( m_wxwindow
->window
,
2429 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2431 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2435 GdkRectangle gdk_rect
;
2436 gdk_rect
.x
= rect
->x
;
2437 gdk_rect
.y
= rect
->y
;
2438 gdk_rect
.width
= rect
->width
;
2439 gdk_rect
.height
= rect
->height
;
2442 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2444 gtk_widget_draw( m_widget
, &gdk_rect
);
2448 wxRegion
wxWindow::GetUpdateRegion() const
2450 return m_updateRegion
;
2453 bool wxWindow::IsExposed( int x
, int y
) const
2455 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2458 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2460 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2463 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2465 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2468 bool wxWindow::IsExposed( const wxRect
& rect
) const
2470 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2473 void wxWindow::Clear()
2475 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2477 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2481 void wxWindow::SetToolTip( const wxString
&tip
)
2485 m_toolTip
->SetTip( tip
);
2489 SetToolTip( new wxToolTip( tip
) );
2492 // setting empty tooltip text does not remove the tooltip any more for
2493 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2496 void wxWindow::SetToolTip( wxToolTip
*tip
)
2500 m_toolTip
->SetTip( (char*) NULL
);
2507 m_toolTip
->Apply( this );
2510 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2512 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2514 #endif // wxUSE_TOOLTIPS
2516 wxColour
wxWindow::GetBackgroundColour() const
2518 return m_backgroundColour
;
2521 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2523 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2525 if (m_backgroundColour
== colour
) return;
2527 m_backgroundColour
= colour
;
2528 if (!m_backgroundColour
.Ok()) return;
2532 GdkWindow
*window
= m_wxwindow
->window
;
2533 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2534 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2537 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2538 if (sysbg
.Red() == colour
.Red() &&
2539 sysbg
.Green() == colour
.Green() &&
2540 sysbg
.Blue() == colour
.Blue())
2542 m_backgroundColour
= wxNullColour
;
2544 m_backgroundColour
= sysbg
;
2552 wxColour
wxWindow::GetForegroundColour() const
2554 return m_foregroundColour
;
2557 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2559 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2561 if (m_foregroundColour
== colour
) return;
2563 m_foregroundColour
= colour
;
2564 if (!m_foregroundColour
.Ok()) return;
2566 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2567 if (sysbg
.Red() == colour
.Red() &&
2568 sysbg
.Green() == colour
.Green() &&
2569 sysbg
.Blue() == colour
.Blue())
2571 m_backgroundColour
= wxNullColour
;
2573 m_backgroundColour
= sysbg
;
2581 GtkStyle
*wxWindow::GetWidgetStyle()
2583 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2587 gtk_widget_get_style( m_widget
) );
2589 return m_widgetStyle
;
2592 void wxWindow::SetWidgetStyle()
2594 GtkStyle
*style
= GetWidgetStyle();
2596 gdk_font_unref( style
->font
);
2597 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2599 if (m_foregroundColour
.Ok())
2601 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2602 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2603 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2604 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2607 if (m_backgroundColour
.Ok())
2609 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2610 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2611 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2612 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2613 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2614 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2615 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2616 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2617 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2621 void wxWindow::ApplyWidgetStyle()
2625 bool wxWindow::Validate()
2627 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2629 wxNode
*node
= m_children
.First();
2632 wxWindow
*child
= (wxWindow
*)node
->Data();
2633 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2637 node
= node
->Next();
2642 bool wxWindow::TransferDataToWindow()
2644 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2646 wxNode
*node
= m_children
.First();
2649 wxWindow
*child
= (wxWindow
*)node
->Data();
2650 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2651 !child
->GetValidator()->TransferToWindow() )
2653 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2656 node
= node
->Next();
2661 bool wxWindow::TransferDataFromWindow()
2663 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2665 wxNode
*node
= m_children
.First();
2668 wxWindow
*child
= (wxWindow
*)node
->Data();
2669 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2673 node
= node
->Next();
2678 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2680 m_acceleratorTable
= accel
;
2683 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2685 TransferDataToWindow();
2688 void wxWindow::InitDialog()
2690 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2692 wxInitDialogEvent
event(GetId());
2693 event
.SetEventObject( this );
2694 GetEventHandler()->ProcessEvent(event
);
2697 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2699 menu
->SetInvokingWindow( win
);
2700 wxNode
*node
= menu
->m_items
.First();
2703 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2704 if (menuitem
->IsSubMenu())
2706 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2708 node
= node
->Next();
2712 static gint gs_pop_x
= 0;
2713 static gint gs_pop_y
= 0;
2715 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2717 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2722 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2724 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2726 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2728 SetInvokingWindow( menu
, this );
2734 GTK_MENU(menu
->m_menu
),
2735 (GtkWidget
*) NULL
, // parent menu shell
2736 (GtkWidget
*) NULL
, // parent menu item
2737 (GtkMenuPositionFunc
) pop_pos_callback
,
2738 (gpointer
) this, // client data
2739 0, // button used to activate it
2740 0 //gs_timeLastClick // the time of activation
2745 #if wxUSE_DRAG_AND_DROP
2747 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2749 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2751 GtkWidget
*dnd_widget
= GetConnectWidget();
2753 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2755 if (m_dropTarget
) delete m_dropTarget
;
2756 m_dropTarget
= dropTarget
;
2758 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2761 wxDropTarget
*wxWindow::GetDropTarget() const
2763 return m_dropTarget
;
2768 GtkWidget
* wxWindow::GetConnectWidget()
2770 GtkWidget
*connect_widget
= m_widget
;
2771 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2773 return connect_widget
;
2776 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2778 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2779 return (window
== m_widget
->window
);
2782 void wxWindow::SetFont( const wxFont
&font
)
2784 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2786 if (((wxFont
*)&font
)->Ok())
2789 m_font
= *wxSWISS_FONT
;
2791 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2792 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2793 sysbg
.Green() == m_backgroundColour
.Green() &&
2794 sysbg
.Blue() == m_backgroundColour
.Blue())
2796 m_backgroundColour
= wxNullColour
;
2798 m_backgroundColour
= sysbg
;
2806 void wxWindow::SetWindowStyleFlag( long flag
)
2808 m_windowStyle
= flag
;
2811 long wxWindow::GetWindowStyleFlag() const
2813 return m_windowStyle
;
2816 void wxWindow::CaptureMouse()
2818 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2820 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2822 GtkWidget
*connect_widget
= GetConnectWidget();
2823 gtk_grab_add( connect_widget
);
2824 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2826 (GDK_BUTTON_PRESS_MASK
|
2827 GDK_BUTTON_RELEASE_MASK
|
2828 GDK_POINTER_MOTION_MASK
),
2835 void wxWindow::ReleaseMouse()
2837 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2839 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2841 GtkWidget
*connect_widget
= GetConnectWidget();
2842 gtk_grab_remove( connect_widget
);
2843 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2844 g_capturing
= FALSE
;
2847 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2851 wxString
wxWindow::GetTitle() const
2853 return (wxString
&)m_windowName
;
2856 wxString
wxWindow::GetLabel() const
2861 void wxWindow::SetName( const wxString
&name
)
2863 m_windowName
= name
;
2866 wxString
wxWindow::GetName() const
2868 return (wxString
&)m_windowName
;
2871 bool wxWindow::IsShown() const
2876 bool wxWindow::IsRetained()
2881 wxWindow
*wxWindow::FindWindow( long id
)
2883 if (id
== m_windowId
) return this;
2884 wxNode
*node
= m_children
.First();
2887 wxWindow
*child
= (wxWindow
*)node
->Data();
2888 wxWindow
*res
= child
->FindWindow( id
);
2889 if (res
) return res
;
2890 node
= node
->Next();
2892 return (wxWindow
*) NULL
;
2895 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2897 if (name
== m_windowName
) return this;
2898 wxNode
*node
= m_children
.First();
2901 wxWindow
*child
= (wxWindow
*)node
->Data();
2902 wxWindow
*res
= child
->FindWindow( name
);
2903 if (res
) return res
;
2904 node
= node
->Next();
2906 return (wxWindow
*) NULL
;
2909 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2910 int range
, bool refresh
)
2912 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2914 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2916 m_hasScrolling
= TRUE
;
2918 if (orient
== wxHORIZONTAL
)
2920 float fpos
= (float)pos
;
2921 float frange
= (float)range
;
2922 float fthumb
= (float)thumbVisible
;
2923 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2924 if (fpos
< 0.0) fpos
= 0.0;
2926 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2927 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2929 SetScrollPos( orient
, pos
, refresh
);
2933 m_oldHorizontalPos
= fpos
;
2935 m_hAdjust
->lower
= 0.0;
2936 m_hAdjust
->upper
= frange
;
2937 m_hAdjust
->value
= fpos
;
2938 m_hAdjust
->step_increment
= 1.0;
2939 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2940 m_hAdjust
->page_size
= fthumb
;
2944 float fpos
= (float)pos
;
2945 float frange
= (float)range
;
2946 float fthumb
= (float)thumbVisible
;
2947 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2948 if (fpos
< 0.0) fpos
= 0.0;
2950 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2951 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2953 SetScrollPos( orient
, pos
, refresh
);
2957 m_oldVerticalPos
= fpos
;
2959 m_vAdjust
->lower
= 0.0;
2960 m_vAdjust
->upper
= frange
;
2961 m_vAdjust
->value
= fpos
;
2962 m_vAdjust
->step_increment
= 1.0;
2963 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2964 m_vAdjust
->page_size
= fthumb
;
2967 if (m_wxwindow
->window
)
2969 if (orient
== wxHORIZONTAL
)
2970 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2972 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2974 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2978 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2980 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2982 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2984 if (orient
== wxHORIZONTAL
)
2986 float fpos
= (float)pos
;
2987 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2988 if (fpos
< 0.0) fpos
= 0.0;
2989 m_oldHorizontalPos
= fpos
;
2991 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2992 m_hAdjust
->value
= fpos
;
2996 float fpos
= (float)pos
;
2997 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2998 if (fpos
< 0.0) fpos
= 0.0;
2999 m_oldVerticalPos
= fpos
;
3001 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3002 m_vAdjust
->value
= fpos
;
3007 if (m_wxwindow
->window
)
3009 if (orient
== wxHORIZONTAL
)
3010 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3012 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3017 int wxWindow::GetScrollThumb( int orient
) const
3019 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3021 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3023 if (orient
== wxHORIZONTAL
)
3024 return (int)(m_hAdjust
->page_size
+0.5);
3026 return (int)(m_vAdjust
->page_size
+0.5);
3029 int wxWindow::GetScrollPos( int orient
) const
3031 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3033 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3035 if (orient
== wxHORIZONTAL
)
3036 return (int)(m_hAdjust
->value
+0.5);
3038 return (int)(m_vAdjust
->value
+0.5);
3041 int wxWindow::GetScrollRange( int orient
) const
3043 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3045 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3047 if (orient
== wxHORIZONTAL
)
3048 return (int)(m_hAdjust
->upper
+0.5);
3050 return (int)(m_vAdjust
->upper
+0.5);
3053 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3055 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3057 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3061 GetClientSize( &cw
, &ch
);
3063 int w
= cw
- abs(dx
);
3064 int h
= ch
- abs(dy
);
3065 if ((h
< 0) || (w
< 0))
3072 if (dx
< 0) s_x
= -dx
;
3073 if (dy
< 0) s_y
= -dy
;
3076 if (dx
> 0) d_x
= dx
;
3077 if (dy
> 0) d_y
= dy
;
3081 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3082 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3085 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3086 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3089 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3090 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3091 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3092 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3094 Refresh( TRUE
, &rect
);
3097 //-------------------------------------------------------------------------------------
3099 //-------------------------------------------------------------------------------------
3101 wxLayoutConstraints
*wxWindow::GetConstraints() const
3103 return m_constraints
;
3106 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3110 UnsetConstraints(m_constraints
);
3111 delete m_constraints
;
3113 m_constraints
= constraints
;
3116 // Make sure other windows know they're part of a 'meaningful relationship'
3117 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3118 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3119 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3120 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3121 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3122 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3123 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3124 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3125 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3126 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3127 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3128 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3129 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3130 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3131 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3132 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3138 void wxWindow::SetAutoLayout( bool autoLayout
)
3140 m_autoLayout
= autoLayout
;
3143 bool wxWindow::GetAutoLayout() const
3145 return m_autoLayout
;
3148 wxSizer
*wxWindow::GetSizer() const
3150 return m_windowSizer
;
3153 void wxWindow::SetSizerParent( wxWindow
*win
)
3155 m_sizerParent
= win
;
3158 wxWindow
*wxWindow::GetSizerParent() const
3160 return m_sizerParent
;
3163 // This removes any dangling pointers to this window
3164 // in other windows' constraintsInvolvedIn lists.
3165 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3169 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3170 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3171 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3172 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3173 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3174 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3175 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3176 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3177 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3178 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3179 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3180 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3181 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3182 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3183 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3184 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3188 // Back-pointer to other windows we're involved with, so if we delete
3189 // this window, we must delete any constraints we're involved with.
3190 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3192 if (!m_constraintsInvolvedIn
)
3193 m_constraintsInvolvedIn
= new wxList
;
3194 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3195 m_constraintsInvolvedIn
->Append(otherWin
);
3198 // REMOVE back-pointer to other windows we're involved with.
3199 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3201 if (m_constraintsInvolvedIn
)
3202 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3205 // Reset any constraints that mention this window
3206 void wxWindow::DeleteRelatedConstraints()
3208 if (m_constraintsInvolvedIn
)
3210 wxNode
*node
= m_constraintsInvolvedIn
->First();
3213 wxWindow
*win
= (wxWindow
*)node
->Data();
3214 wxNode
*next
= node
->Next();
3215 wxLayoutConstraints
*constr
= win
->GetConstraints();
3217 // Reset any constraints involving this window
3220 constr
->left
.ResetIfWin((wxWindow
*)this);
3221 constr
->top
.ResetIfWin((wxWindow
*)this);
3222 constr
->right
.ResetIfWin((wxWindow
*)this);
3223 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3224 constr
->width
.ResetIfWin((wxWindow
*)this);
3225 constr
->height
.ResetIfWin((wxWindow
*)this);
3226 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3227 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3232 delete m_constraintsInvolvedIn
;
3233 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3237 void wxWindow::SetSizer(wxSizer
*sizer
)
3239 m_windowSizer
= sizer
;
3241 sizer
->SetSizerParent((wxWindow
*)this);
3248 bool wxWindow::Layout()
3250 if (GetConstraints())
3253 GetClientSize(&w
, &h
);
3254 GetConstraints()->width
.SetValue(w
);
3255 GetConstraints()->height
.SetValue(h
);
3258 // If top level (one sizer), evaluate the sizer's constraints.
3262 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3263 GetSizer()->LayoutPhase1(&noChanges
);
3264 GetSizer()->LayoutPhase2(&noChanges
);
3265 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3270 // Otherwise, evaluate child constraints
3271 ResetConstraints(); // Mark all constraints as unevaluated
3272 DoPhase(1); // Just one phase need if no sizers involved
3274 SetConstraintSizes(); // Recursively set the real window sizes
3280 // Do a phase of evaluating constraints:
3281 // the default behaviour. wxSizers may do a similar
3282 // thing, but also impose their own 'constraints'
3283 // and order the evaluation differently.
3284 bool wxWindow::LayoutPhase1(int *noChanges
)
3286 wxLayoutConstraints
*constr
= GetConstraints();
3289 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3295 bool wxWindow::LayoutPhase2(int *noChanges
)
3305 // Do a phase of evaluating child constraints
3306 bool wxWindow::DoPhase(int phase
)
3308 int noIterations
= 0;
3309 int maxIterations
= 500;
3313 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3317 wxNode
*node
= m_children
.First();
3320 wxWindow
*child
= (wxWindow
*)node
->Data();
3321 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3323 wxLayoutConstraints
*constr
= child
->GetConstraints();
3326 if (succeeded
.Member(child
))
3331 int tempNoChanges
= 0;
3332 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3333 noChanges
+= tempNoChanges
;
3336 succeeded
.Append(child
);
3341 node
= node
->Next();
3348 void wxWindow::ResetConstraints()
3350 wxLayoutConstraints
*constr
= GetConstraints();
3353 constr
->left
.SetDone(FALSE
);
3354 constr
->top
.SetDone(FALSE
);
3355 constr
->right
.SetDone(FALSE
);
3356 constr
->bottom
.SetDone(FALSE
);
3357 constr
->width
.SetDone(FALSE
);
3358 constr
->height
.SetDone(FALSE
);
3359 constr
->centreX
.SetDone(FALSE
);
3360 constr
->centreY
.SetDone(FALSE
);
3362 wxNode
*node
= m_children
.First();
3365 wxWindow
*win
= (wxWindow
*)node
->Data();
3366 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3367 win
->ResetConstraints();
3368 node
= node
->Next();
3372 // Need to distinguish between setting the 'fake' size for
3373 // windows and sizers, and setting the real values.
3374 void wxWindow::SetConstraintSizes(bool recurse
)
3376 wxLayoutConstraints
*constr
= GetConstraints();
3377 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3378 constr
->width
.GetDone() && constr
->height
.GetDone())
3380 int x
= constr
->left
.GetValue();
3381 int y
= constr
->top
.GetValue();
3382 int w
= constr
->width
.GetValue();
3383 int h
= constr
->height
.GetValue();
3385 // If we don't want to resize this window, just move it...
3386 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3387 (constr
->height
.GetRelationship() != wxAsIs
))
3389 // Calls Layout() recursively. AAAGH. How can we stop that.
3390 // Simply take Layout() out of non-top level OnSizes.
3391 SizerSetSize(x
, y
, w
, h
);
3400 char *windowClass
= this->GetClassInfo()->GetClassName();
3403 if (GetName() == "")
3404 winName
= "unnamed";
3406 winName
= GetName();
3407 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3408 (const char *)windowClass
,
3409 (const char *)winName
);
3410 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3411 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3412 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3413 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3414 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3419 wxNode
*node
= m_children
.First();
3422 wxWindow
*win
= (wxWindow
*)node
->Data();
3423 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3424 win
->SetConstraintSizes();
3425 node
= node
->Next();
3430 // This assumes that all sizers are 'on' the same
3431 // window, i.e. the parent of this window.
3432 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3434 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3435 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3439 m_sizerParent
->GetPosition(&xp
, &yp
);
3440 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3445 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3449 TransformSizerToActual(&xx
, &yy
);
3450 SetSize(xx
, yy
, w
, h
);
3453 void wxWindow::SizerMove(int x
, int y
)
3457 TransformSizerToActual(&xx
, &yy
);
3461 // Only set the size/position of the constraint (if any)
3462 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3464 wxLayoutConstraints
*constr
= GetConstraints();
3469 constr
->left
.SetValue(x
);
3470 constr
->left
.SetDone(TRUE
);
3474 constr
->top
.SetValue(y
);
3475 constr
->top
.SetDone(TRUE
);
3479 constr
->width
.SetValue(w
);
3480 constr
->width
.SetDone(TRUE
);
3484 constr
->height
.SetValue(h
);
3485 constr
->height
.SetDone(TRUE
);
3490 void wxWindow::MoveConstraint(int x
, int y
)
3492 wxLayoutConstraints
*constr
= GetConstraints();
3497 constr
->left
.SetValue(x
);
3498 constr
->left
.SetDone(TRUE
);
3502 constr
->top
.SetValue(y
);
3503 constr
->top
.SetDone(TRUE
);
3508 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3510 wxLayoutConstraints
*constr
= GetConstraints();
3513 *w
= constr
->width
.GetValue();
3514 *h
= constr
->height
.GetValue();
3520 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3522 wxLayoutConstraints
*constr
= GetConstraints();
3525 *w
= constr
->width
.GetValue();
3526 *h
= constr
->height
.GetValue();
3529 GetClientSize(w
, h
);
3532 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3534 wxLayoutConstraints
*constr
= GetConstraints();
3537 *x
= constr
->left
.GetValue();
3538 *y
= constr
->top
.GetValue();