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
))
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
;
1354 m_toolTip
= (wxToolTip
*) NULL
;
1357 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1358 const wxPoint
&pos
, const wxSize
&size
,
1359 long style
, const wxString
&name
)
1361 m_insertCallback
= wxInsertChildInWindow
;
1362 Create( parent
, id
, pos
, size
, style
, name
);
1365 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1366 const wxPoint
&pos
, const wxSize
&size
,
1367 long style
, const wxString
&name
)
1371 m_needParent
= TRUE
;
1373 PreCreation( parent
, id
, pos
, size
, style
, name
);
1375 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1376 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1379 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1382 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1385 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1386 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1389 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1390 scroll_class
->scrollbar_spacing
= 0;
1392 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1394 m_oldHorizontalPos
= 0.0;
1395 m_oldVerticalPos
= 0.0;
1397 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1398 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1400 m_wxwindow
= gtk_myfixed_new();
1403 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1406 #ifdef NEW_GTK_SCROLL_CODE
1407 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1408 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1410 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1411 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1415 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1418 if (m_windowStyle
& wxRAISED_BORDER
)
1420 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1422 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1424 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1428 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1431 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1433 /* we now allow a window to get the focus as long as it
1434 doesn't have any children. */
1435 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1436 m_acceptsFocus
= FALSE
;
1440 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1441 m_acceptsFocus
= TRUE
;
1444 // shut the viewport up
1445 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1446 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1448 // I _really_ don't want scrollbars in the beginning
1449 m_vAdjust
->lower
= 0.0;
1450 m_vAdjust
->upper
= 1.0;
1451 m_vAdjust
->value
= 0.0;
1452 m_vAdjust
->step_increment
= 1.0;
1453 m_vAdjust
->page_increment
= 1.0;
1454 m_vAdjust
->page_size
= 5.0;
1455 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1456 m_hAdjust
->lower
= 0.0;
1457 m_hAdjust
->upper
= 1.0;
1458 m_hAdjust
->value
= 0.0;
1459 m_hAdjust
->step_increment
= 1.0;
1460 m_hAdjust
->page_increment
= 1.0;
1461 m_hAdjust
->page_size
= 5.0;
1462 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1464 // these handlers block mouse events to any window during scrolling
1465 // such as motion events and prevent GTK and wxWindows from fighting
1466 // over where the slider should be
1468 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1469 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1471 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1472 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1474 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1475 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1477 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1478 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1480 // these handers het notified when screen updates are required either when
1481 // scrolling or when the window size (and therefore scrollbar configuration)
1484 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1485 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1486 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1487 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1489 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1490 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1491 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1492 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1494 gtk_widget_show( m_wxwindow
);
1496 if (m_parent
) m_parent
->AddChild( this );
1498 (m_parent
->m_insertCallback
)( m_parent
, this );
1507 wxWindow::~wxWindow()
1511 #if wxUSE_DRAG_AND_DROP
1512 if (m_dropTarget
) delete m_dropTarget
;
1515 if (m_toolTip
) delete m_toolTip
;
1517 if (m_parent
) m_parent
->RemoveChild( this );
1518 if (m_widget
) Show( FALSE
);
1522 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1524 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1526 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1528 if (m_widget
) gtk_widget_destroy( m_widget
);
1530 if (m_cursor
) delete m_cursor
;
1532 DeleteRelatedConstraints();
1535 // This removes any dangling pointers to this window
1536 // in other windows' constraintsInvolvedIn lists.
1537 UnsetConstraints(m_constraints
);
1538 delete m_constraints
;
1539 m_constraints
= (wxLayoutConstraints
*) NULL
;
1543 delete m_windowSizer
;
1544 m_windowSizer
= (wxSizer
*) NULL
;
1546 // If this is a child of a sizer, remove self from parent
1547 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1549 // Just in case the window has been Closed, but
1550 // we're then deleting immediately: don't leave
1551 // dangling pointers.
1552 wxPendingDelete
.DeleteObject(this);
1554 // Just in case we've loaded a top-level window via
1555 // wxWindow::LoadNativeDialog but we weren't a dialog
1557 wxTopLevelWindows
.DeleteObject(this);
1559 if (m_windowValidator
) delete m_windowValidator
;
1561 if (m_clientObject
) delete m_clientObject
;
1564 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1565 const wxPoint
&pos
, const wxSize
&size
,
1566 long style
, const wxString
&name
)
1568 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1570 m_widget
= (GtkWidget
*) NULL
;
1571 m_wxwindow
= (GtkWidget
*) NULL
;
1574 m_children
.DeleteContents( FALSE
);
1577 if (m_width
== -1) m_width
= 20;
1579 if (m_height
== -1) m_height
= 20;
1584 if (!m_needParent
) // some reasonable defaults
1588 m_x
= (gdk_screen_width () - m_width
) / 2;
1589 if (m_x
< 10) m_x
= 10;
1593 m_y
= (gdk_screen_height () - m_height
) / 2;
1594 if (m_y
< 10) m_y
= 10;
1605 m_eventHandler
= this;
1607 m_windowId
= id
== -1 ? wxNewId() : id
;
1611 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1612 m_font
= *wxSWISS_FONT
;
1613 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1614 m_foregroundColour
= *wxBLACK
;
1615 m_windowStyle
= style
;
1616 m_windowName
= name
;
1618 m_constraints
= (wxLayoutConstraints
*) NULL
;
1619 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1620 m_windowSizer
= (wxSizer
*) NULL
;
1621 m_sizerParent
= (wxWindow
*) NULL
;
1622 m_autoLayout
= FALSE
;
1624 m_hasScrolling
= FALSE
;
1625 m_isScrolling
= FALSE
;
1626 m_hAdjust
= (GtkAdjustment
*) NULL
;
1627 m_vAdjust
= (GtkAdjustment
*) NULL
;
1628 m_oldHorizontalPos
= 0.0;
1629 m_oldVerticalPos
= 0.0;
1634 #if wxUSE_DRAG_AND_DROP
1635 m_dropTarget
= (wxDropTarget
*) NULL
;
1638 m_windowValidator
= (wxValidator
*) NULL
;
1639 m_scrollGC
= (GdkGC
*) NULL
;
1640 m_widgetStyle
= (GtkStyle
*) NULL
;
1642 m_clientObject
= (wxClientData
*)NULL
;
1643 m_clientData
= NULL
;
1645 m_isStaticBox
= FALSE
;
1646 m_toolTip
= (wxToolTip
*) NULL
;
1649 void wxWindow::PostCreation()
1653 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1654 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1656 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1657 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1660 ConnectWidget( GetConnectWidget() );
1662 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1664 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1666 SetCursor( *wxSTANDARD_CURSOR
);
1671 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1673 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1674 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1676 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1677 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1679 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1680 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1682 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1683 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1685 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1686 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1688 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1689 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1691 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1692 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1694 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1695 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1697 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1698 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1701 bool wxWindow::HasVMT()
1706 bool wxWindow::Close( bool force
)
1708 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1710 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1711 event
.SetEventObject(this);
1712 event
.SetForce(force
);
1714 return GetEventHandler()->ProcessEvent(event
);
1717 bool wxWindow::Destroy()
1719 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1726 bool wxWindow::DestroyChildren()
1729 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1732 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1735 if (m_children
.Member(child
)) delete node
;
1741 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1743 // are we to set fonts here ?
1746 wxPoint
wxWindow::GetClientAreaOrigin() const
1748 return wxPoint(0,0);
1751 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1753 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1755 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1761 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1763 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1764 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1766 if (m_resizing
) return; // I don't like recursions
1769 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1771 // don't set the size for children of wxNotebook, just take the values.
1779 int old_width
= m_width
;
1780 int old_height
= m_height
;
1782 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1784 if (x
!= -1) m_x
= x
;
1785 if (y
!= -1) m_y
= y
;
1786 if (width
!= -1) m_width
= width
;
1787 if (height
!= -1) m_height
= height
;
1797 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1799 if (width
== -1) m_width
= 80;
1802 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1804 if (height
== -1) m_height
= 26;
1807 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1808 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1809 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1810 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1812 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1813 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1815 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1816 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1821 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1822 event
.SetEventObject( this );
1823 GetEventHandler()->ProcessEvent( event
);
1828 void wxWindow::OnInternalIdle()
1833 void wxWindow::SetSize( int width
, int height
)
1835 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1838 void wxWindow::Move( int x
, int y
)
1840 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1843 void wxWindow::GetSize( int *width
, int *height
) const
1845 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1847 if (width
) (*width
) = m_width
;
1848 if (height
) (*height
) = m_height
;
1851 void wxWindow::SetClientSize( int width
, int height
)
1853 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1857 SetSize( width
, height
);
1864 if (!m_hasScrolling
)
1866 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1868 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1869 (m_windowStyle
& wxSUNKEN_BORDER
))
1871 dw
+= 2 * window_class
->xthickness
;
1872 dh
+= 2 * window_class
->ythickness
;
1877 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1878 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1880 #ifdef NEW_GTK_SCROLL_CODE
1881 GtkWidget
*viewport
= scroll_window
->child
;
1883 GtkWidget
*viewport
= scroll_window
->viewport
;
1886 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1888 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1889 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1891 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1892 (m_windowStyle
& wxSUNKEN_BORDER
))
1894 dw
+= 2 * viewport_class
->xthickness
;
1895 dh
+= 2 * viewport_class
->ythickness
;
1898 if (scroll_window
->vscrollbar_visible
)
1900 dw
+= vscrollbar
->allocation
.width
;
1901 dw
+= scroll_class
->scrollbar_spacing
;
1904 if (scroll_window
->hscrollbar_visible
)
1906 dh
+= hscrollbar
->allocation
.height
;
1907 dw
+= scroll_class
->scrollbar_spacing
;
1911 SetSize( width
+dw
, height
+dh
);
1915 void wxWindow::GetClientSize( int *width
, int *height
) const
1917 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1921 if (width
) (*width
) = m_width
;
1922 if (height
) (*height
) = m_height
;
1929 if (!m_hasScrolling
)
1931 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1933 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1934 (m_windowStyle
& wxSUNKEN_BORDER
))
1936 dw
+= 2 * window_class
->xthickness
;
1937 dh
+= 2 * window_class
->ythickness
;
1942 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1943 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1945 #ifdef NEW_GTK_SCROLL_CODE
1946 GtkWidget
*viewport
= scroll_window
->child
;
1948 GtkWidget
*viewport
= scroll_window
->viewport
;
1951 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1953 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1954 (m_windowStyle
& wxSUNKEN_BORDER
))
1956 dw
+= 2 * viewport_class
->xthickness
;
1957 dh
+= 2 * viewport_class
->ythickness
;
1960 if (scroll_window
->vscrollbar_visible
)
1962 // dw += vscrollbar->allocation.width;
1963 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1964 dw
+= scroll_class
->scrollbar_spacing
;
1967 if (scroll_window
->hscrollbar_visible
)
1969 // dh += hscrollbar->allocation.height;
1971 dh
+= scroll_class
->scrollbar_spacing
;
1975 if (width
) (*width
) = m_width
- dw
;
1976 if (height
) (*height
) = m_height
- dh
;
1980 void wxWindow::GetPosition( int *x
, int *y
) const
1982 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1988 void wxWindow::ClientToScreen( int *x
, int *y
)
1990 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1992 GdkWindow
*source
= (GdkWindow
*) NULL
;
1994 source
= m_wxwindow
->window
;
1996 source
= m_widget
->window
;
2000 gdk_window_get_origin( source
, &org_x
, &org_y
);
2004 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2006 org_x
+= m_widget
->allocation
.x
;
2007 org_y
+= m_widget
->allocation
.y
;
2011 wxPoint
pt(GetClientAreaOrigin());
2019 void wxWindow::ScreenToClient( int *x
, int *y
)
2021 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2023 GdkWindow
*source
= (GdkWindow
*) NULL
;
2025 source
= m_wxwindow
->window
;
2027 source
= m_widget
->window
;
2031 gdk_window_get_origin( source
, &org_x
, &org_y
);
2035 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2037 org_x
+= m_widget
->allocation
.x
;
2038 org_y
+= m_widget
->allocation
.y
;
2042 wxPoint
pt(GetClientAreaOrigin());
2050 void wxWindow::Centre( int direction
)
2052 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2061 m_parent
->GetSize( &p_w
, &p_h
);
2062 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2063 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2067 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2068 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2074 void wxWindow::Fit()
2076 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2080 wxNode
*node
= m_children
.First();
2083 wxWindow
*win
= (wxWindow
*)node
->Data();
2085 win
->GetPosition(&wx
, &wy
);
2086 win
->GetSize(&ww
, &wh
);
2087 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2088 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2090 node
= node
->Next();
2093 SetClientSize(maxX
+ 7, maxY
+ 14);
2096 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2098 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2106 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2108 // if (GetAutoLayout()) Layout();
2111 bool wxWindow::Show( bool show
)
2113 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2116 gtk_widget_show( m_widget
);
2118 gtk_widget_hide( m_widget
);
2125 void wxWindow::Enable( bool enable
)
2127 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2129 m_isEnabled
= enable
;
2131 gtk_widget_set_sensitive( m_widget
, enable
);
2132 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2135 int wxWindow::GetCharHeight() const
2137 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2139 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2141 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2143 return font
->ascent
+ font
->descent
;
2146 int wxWindow::GetCharWidth() const
2148 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2150 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2152 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2154 return gdk_string_width( font
, "H" );
2157 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2158 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2160 wxFont fontToUse
= m_font
;
2161 if (theFont
) fontToUse
= *theFont
;
2163 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2165 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2166 if (x
) (*x
) = gdk_string_width( font
, string
);
2167 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2168 if (descent
) (*descent
) = font
->descent
;
2169 if (externalLeading
) (*externalLeading
) = 0; // ??
2172 void wxWindow::MakeModal( bool modal
)
2176 // Disable all other windows
2177 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2179 wxNode
*node
= wxTopLevelWindows
.First();
2182 wxWindow
*win
= (wxWindow
*)node
->Data();
2183 if (win
!= this) win
->Enable(!modal
);
2185 node
= node
->Next();
2190 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2192 event
.SetEventType( wxEVT_CHAR
);
2194 if (!GetEventHandler()->ProcessEvent( event
))
2200 void wxWindow::SetFocus()
2202 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2204 GtkWidget
*connect_widget
= GetConnectWidget();
2207 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2209 gtk_widget_grab_focus (connect_widget
);
2211 else if (GTK_IS_CONTAINER(connect_widget
))
2213 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2221 wxWindow
*wxWindow::FindFocus()
2223 return g_focusWindow
;
2226 bool wxWindow::AcceptsFocus() const
2228 return IsEnabled() && IsShown() && m_acceptsFocus
;
2231 bool wxWindow::OnClose()
2236 void wxWindow::AddChild( wxWindow
*child
)
2238 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2239 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2241 m_children
.Append( child
);
2244 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2246 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2248 wxWindow
*oldParent
= GetParent();
2250 if (oldParent
) oldParent
->RemoveChild( this );
2252 gtk_widget_unparent( m_widget
);
2256 newParent
->AddChild( this );
2257 (newParent
->m_insertCallback
)( newParent
, this );
2263 void wxWindow::RemoveChild( wxWindow
*child
)
2265 m_children
.DeleteObject( child
);
2266 child
->m_parent
= (wxWindow
*) NULL
;
2269 void wxWindow::SetReturnCode( int retCode
)
2271 m_retCode
= retCode
;
2274 int wxWindow::GetReturnCode()
2279 void wxWindow::Raise()
2281 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2283 if (m_widget
) gdk_window_raise( m_widget
->window
);
2286 void wxWindow::Lower()
2288 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2290 if (m_widget
) gdk_window_lower( m_widget
->window
);
2293 wxEvtHandler
*wxWindow::GetEventHandler() const
2295 return m_eventHandler
;
2298 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2300 m_eventHandler
= handler
;
2303 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2305 handler
->SetNextHandler(GetEventHandler());
2306 SetEventHandler(handler
);
2309 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2311 if (GetEventHandler())
2313 wxEvtHandler
*handlerA
= GetEventHandler();
2314 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2315 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2316 SetEventHandler(handlerB
);
2320 return (wxEvtHandler
*) NULL
;
2326 return (wxEvtHandler
*) NULL
;
2329 wxValidator
*wxWindow::GetValidator()
2331 return m_windowValidator
;
2334 void wxWindow::SetValidator( const wxValidator
& validator
)
2336 if (m_windowValidator
) delete m_windowValidator
;
2337 m_windowValidator
= validator
.Clone();
2338 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2341 void wxWindow::SetClientObject( wxClientData
*data
)
2343 if (m_clientObject
) delete m_clientObject
;
2344 m_clientObject
= data
;
2347 wxClientData
*wxWindow::GetClientObject()
2349 return m_clientObject
;
2352 void wxWindow::SetClientData( void *data
)
2354 m_clientData
= data
;
2357 void *wxWindow::GetClientData()
2359 return m_clientData
;
2362 bool wxWindow::IsBeingDeleted()
2367 void wxWindow::SetId( wxWindowID id
)
2372 wxWindowID
wxWindow::GetId() const
2377 void wxWindow::SetCursor( const wxCursor
&cursor
)
2379 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2383 if (cursor
== *m_cursor
) return;
2388 *m_cursor
= *wxSTANDARD_CURSOR
;
2391 if ((m_widget
) && (m_widget
->window
))
2392 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2394 if ((m_wxwindow
) && (m_wxwindow
->window
))
2395 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2398 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2403 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2405 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2407 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2411 gdk_window_clear_area( m_wxwindow
->window
,
2425 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2427 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2431 GdkRectangle gdk_rect
;
2432 gdk_rect
.x
= rect
->x
;
2433 gdk_rect
.y
= rect
->y
;
2434 gdk_rect
.width
= rect
->width
;
2435 gdk_rect
.height
= rect
->height
;
2438 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2440 gtk_widget_draw( m_widget
, &gdk_rect
);
2444 wxRegion
wxWindow::GetUpdateRegion() const
2446 return m_updateRegion
;
2449 bool wxWindow::IsExposed( int x
, int y
) const
2451 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2454 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2456 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2459 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2461 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2464 bool wxWindow::IsExposed( const wxRect
& rect
) const
2466 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2469 void wxWindow::Clear()
2471 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2473 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2476 void wxWindow::SetToolTip( const wxString
&tip
)
2478 SetToolTip( new wxToolTip( tip
) );
2481 void wxWindow::SetToolTip( wxToolTip
*tip
)
2483 if (m_toolTip
) delete m_toolTip
;
2487 if (m_toolTip
) m_toolTip
->Create( GetConnectWidget() );
2490 wxToolTip
& wxWindow::GetToolTip()
2493 wxLogError( "No tooltip set." );
2498 wxColour
wxWindow::GetBackgroundColour() const
2500 return m_backgroundColour
;
2503 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2505 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2507 if (m_backgroundColour
== colour
) return;
2509 m_backgroundColour
= colour
;
2510 if (!m_backgroundColour
.Ok()) return;
2514 GdkWindow
*window
= m_wxwindow
->window
;
2515 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2516 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2517 gdk_window_clear( window
);
2520 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2521 if (sysbg
.Red() == colour
.Red() &&
2522 sysbg
.Green() == colour
.Green() &&
2523 sysbg
.Blue() == colour
.Blue())
2525 m_backgroundColour
= wxNullColour
;
2527 m_backgroundColour
= sysbg
;
2535 wxColour
wxWindow::GetForegroundColour() const
2537 return m_foregroundColour
;
2540 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2542 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2544 if (m_foregroundColour
== colour
) return;
2546 m_foregroundColour
= colour
;
2547 if (!m_foregroundColour
.Ok()) return;
2549 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2550 if (sysbg
.Red() == colour
.Red() &&
2551 sysbg
.Green() == colour
.Green() &&
2552 sysbg
.Blue() == colour
.Blue())
2554 m_backgroundColour
= wxNullColour
;
2556 m_backgroundColour
= sysbg
;
2564 GtkStyle
*wxWindow::GetWidgetStyle()
2566 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2570 gtk_widget_get_style( m_widget
) );
2572 return m_widgetStyle
;
2575 void wxWindow::SetWidgetStyle()
2577 GtkStyle
*style
= GetWidgetStyle();
2579 gdk_font_unref( style
->font
);
2580 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2582 if (m_foregroundColour
.Ok())
2584 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2585 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2586 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2587 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2590 if (m_backgroundColour
.Ok())
2592 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2593 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2594 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2595 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2596 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2597 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2598 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2599 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2600 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2604 void wxWindow::ApplyWidgetStyle()
2608 bool wxWindow::Validate()
2610 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2612 wxNode
*node
= m_children
.First();
2615 wxWindow
*child
= (wxWindow
*)node
->Data();
2616 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2620 node
= node
->Next();
2625 bool wxWindow::TransferDataToWindow()
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() && */
2634 !child
->GetValidator()->TransferToWindow() )
2636 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2639 node
= node
->Next();
2644 bool wxWindow::TransferDataFromWindow()
2646 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2648 wxNode
*node
= m_children
.First();
2651 wxWindow
*child
= (wxWindow
*)node
->Data();
2652 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2656 node
= node
->Next();
2661 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2663 m_acceleratorTable
= accel
;
2666 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2668 TransferDataToWindow();
2671 void wxWindow::InitDialog()
2673 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2675 wxInitDialogEvent
event(GetId());
2676 event
.SetEventObject( this );
2677 GetEventHandler()->ProcessEvent(event
);
2680 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2682 menu
->SetInvokingWindow( win
);
2683 wxNode
*node
= menu
->m_items
.First();
2686 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2687 if (menuitem
->IsSubMenu())
2689 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2691 node
= node
->Next();
2695 static gint gs_pop_x
= 0;
2696 static gint gs_pop_y
= 0;
2698 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2700 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2705 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2707 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2709 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2711 SetInvokingWindow( menu
, this );
2717 GTK_MENU(menu
->m_menu
),
2718 (GtkWidget
*) NULL
, // parent menu shell
2719 (GtkWidget
*) NULL
, // parent menu item
2720 (GtkMenuPositionFunc
) pop_pos_callback
,
2721 (gpointer
) this, // client data
2722 0, // button used to activate it
2723 0 //gs_timeLastClick // the time of activation
2728 #if wxUSE_DRAG_AND_DROP
2730 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2732 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2734 GtkWidget
*dnd_widget
= GetConnectWidget();
2736 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2738 if (m_dropTarget
) delete m_dropTarget
;
2739 m_dropTarget
= dropTarget
;
2741 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2744 wxDropTarget
*wxWindow::GetDropTarget() const
2746 return m_dropTarget
;
2751 GtkWidget
* wxWindow::GetConnectWidget()
2753 GtkWidget
*connect_widget
= m_widget
;
2754 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2756 return connect_widget
;
2759 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2761 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2762 return (window
== m_widget
->window
);
2765 void wxWindow::SetFont( const wxFont
&font
)
2767 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2769 if (((wxFont
*)&font
)->Ok())
2772 m_font
= *wxSWISS_FONT
;
2774 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2775 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2776 sysbg
.Green() == m_backgroundColour
.Green() &&
2777 sysbg
.Blue() == m_backgroundColour
.Blue())
2779 m_backgroundColour
= wxNullColour
;
2781 m_backgroundColour
= sysbg
;
2789 void wxWindow::SetWindowStyleFlag( long flag
)
2791 m_windowStyle
= flag
;
2794 long wxWindow::GetWindowStyleFlag() const
2796 return m_windowStyle
;
2799 void wxWindow::CaptureMouse()
2801 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2803 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2805 GtkWidget
*connect_widget
= GetConnectWidget();
2806 gtk_grab_add( connect_widget
);
2807 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2809 (GDK_BUTTON_PRESS_MASK
|
2810 GDK_BUTTON_RELEASE_MASK
|
2811 GDK_POINTER_MOTION_MASK
),
2818 void wxWindow::ReleaseMouse()
2820 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2822 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2824 GtkWidget
*connect_widget
= GetConnectWidget();
2825 gtk_grab_remove( connect_widget
);
2826 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2827 g_capturing
= FALSE
;
2830 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2834 wxString
wxWindow::GetTitle() const
2836 return (wxString
&)m_windowName
;
2839 wxString
wxWindow::GetLabel() const
2844 void wxWindow::SetName( const wxString
&name
)
2846 m_windowName
= name
;
2849 wxString
wxWindow::GetName() const
2851 return (wxString
&)m_windowName
;
2854 bool wxWindow::IsShown() const
2859 bool wxWindow::IsRetained()
2864 wxWindow
*wxWindow::FindWindow( long id
)
2866 if (id
== m_windowId
) return this;
2867 wxNode
*node
= m_children
.First();
2870 wxWindow
*child
= (wxWindow
*)node
->Data();
2871 wxWindow
*res
= child
->FindWindow( id
);
2872 if (res
) return res
;
2873 node
= node
->Next();
2875 return (wxWindow
*) NULL
;
2878 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2880 if (name
== m_windowName
) return this;
2881 wxNode
*node
= m_children
.First();
2884 wxWindow
*child
= (wxWindow
*)node
->Data();
2885 wxWindow
*res
= child
->FindWindow( name
);
2886 if (res
) return res
;
2887 node
= node
->Next();
2889 return (wxWindow
*) NULL
;
2892 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2893 int range
, bool refresh
)
2895 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2897 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2899 m_hasScrolling
= TRUE
;
2901 if (orient
== wxHORIZONTAL
)
2903 float fpos
= (float)pos
;
2904 float frange
= (float)range
;
2905 float fthumb
= (float)thumbVisible
;
2906 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2907 if (fpos
< 0.0) fpos
= 0.0;
2909 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2910 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2912 SetScrollPos( orient
, pos
, refresh
);
2916 m_oldHorizontalPos
= fpos
;
2918 m_hAdjust
->lower
= 0.0;
2919 m_hAdjust
->upper
= frange
;
2920 m_hAdjust
->value
= fpos
;
2921 m_hAdjust
->step_increment
= 1.0;
2922 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2923 m_hAdjust
->page_size
= fthumb
;
2927 float fpos
= (float)pos
;
2928 float frange
= (float)range
;
2929 float fthumb
= (float)thumbVisible
;
2930 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2931 if (fpos
< 0.0) fpos
= 0.0;
2933 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2934 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2936 SetScrollPos( orient
, pos
, refresh
);
2940 m_oldVerticalPos
= fpos
;
2942 m_vAdjust
->lower
= 0.0;
2943 m_vAdjust
->upper
= frange
;
2944 m_vAdjust
->value
= fpos
;
2945 m_vAdjust
->step_increment
= 1.0;
2946 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2947 m_vAdjust
->page_size
= fthumb
;
2950 if (m_wxwindow
->window
)
2952 if (orient
== wxHORIZONTAL
)
2953 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2955 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2957 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2961 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2963 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2965 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2967 if (orient
== wxHORIZONTAL
)
2969 float fpos
= (float)pos
;
2970 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2971 if (fpos
< 0.0) fpos
= 0.0;
2972 m_oldHorizontalPos
= fpos
;
2974 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2975 m_hAdjust
->value
= fpos
;
2979 float fpos
= (float)pos
;
2980 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2981 if (fpos
< 0.0) fpos
= 0.0;
2982 m_oldVerticalPos
= fpos
;
2984 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2985 m_vAdjust
->value
= fpos
;
2990 if (m_wxwindow
->window
)
2992 if (orient
== wxHORIZONTAL
)
2993 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2995 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3000 int wxWindow::GetScrollThumb( int orient
) const
3002 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3004 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3006 if (orient
== wxHORIZONTAL
)
3007 return (int)(m_hAdjust
->page_size
+0.5);
3009 return (int)(m_vAdjust
->page_size
+0.5);
3012 int wxWindow::GetScrollPos( int orient
) const
3014 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3016 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3018 if (orient
== wxHORIZONTAL
)
3019 return (int)(m_hAdjust
->value
+0.5);
3021 return (int)(m_vAdjust
->value
+0.5);
3024 int wxWindow::GetScrollRange( int orient
) const
3026 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3028 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3030 if (orient
== wxHORIZONTAL
)
3031 return (int)(m_hAdjust
->upper
+0.5);
3033 return (int)(m_vAdjust
->upper
+0.5);
3036 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3038 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3040 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3044 GetClientSize( &cw
, &ch
);
3046 int w
= cw
- abs(dx
);
3047 int h
= ch
- abs(dy
);
3048 if ((h
< 0) || (w
< 0))
3055 if (dx
< 0) s_x
= -dx
;
3056 if (dy
< 0) s_y
= -dy
;
3059 if (dx
> 0) d_x
= dx
;
3060 if (dy
> 0) d_y
= dy
;
3064 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3065 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3068 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3069 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3072 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3073 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3074 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3075 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3077 Refresh( TRUE
, &rect
);
3080 //-------------------------------------------------------------------------------------
3082 //-------------------------------------------------------------------------------------
3084 wxLayoutConstraints
*wxWindow::GetConstraints() const
3086 return m_constraints
;
3089 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3093 UnsetConstraints(m_constraints
);
3094 delete m_constraints
;
3096 m_constraints
= constraints
;
3099 // Make sure other windows know they're part of a 'meaningful relationship'
3100 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3101 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3102 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3103 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3104 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3105 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3106 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3107 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3108 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3109 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3110 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3111 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3112 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3113 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3114 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3115 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3121 void wxWindow::SetAutoLayout( bool autoLayout
)
3123 m_autoLayout
= autoLayout
;
3126 bool wxWindow::GetAutoLayout() const
3128 return m_autoLayout
;
3131 wxSizer
*wxWindow::GetSizer() const
3133 return m_windowSizer
;
3136 void wxWindow::SetSizerParent( wxWindow
*win
)
3138 m_sizerParent
= win
;
3141 wxWindow
*wxWindow::GetSizerParent() const
3143 return m_sizerParent
;
3146 // This removes any dangling pointers to this window
3147 // in other windows' constraintsInvolvedIn lists.
3148 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3152 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3153 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3154 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3155 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3156 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3157 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3158 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3159 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3160 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3161 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3162 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3163 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3164 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3165 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3166 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3167 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3171 // Back-pointer to other windows we're involved with, so if we delete
3172 // this window, we must delete any constraints we're involved with.
3173 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3175 if (!m_constraintsInvolvedIn
)
3176 m_constraintsInvolvedIn
= new wxList
;
3177 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3178 m_constraintsInvolvedIn
->Append(otherWin
);
3181 // REMOVE back-pointer to other windows we're involved with.
3182 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3184 if (m_constraintsInvolvedIn
)
3185 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3188 // Reset any constraints that mention this window
3189 void wxWindow::DeleteRelatedConstraints()
3191 if (m_constraintsInvolvedIn
)
3193 wxNode
*node
= m_constraintsInvolvedIn
->First();
3196 wxWindow
*win
= (wxWindow
*)node
->Data();
3197 wxNode
*next
= node
->Next();
3198 wxLayoutConstraints
*constr
= win
->GetConstraints();
3200 // Reset any constraints involving this window
3203 constr
->left
.ResetIfWin((wxWindow
*)this);
3204 constr
->top
.ResetIfWin((wxWindow
*)this);
3205 constr
->right
.ResetIfWin((wxWindow
*)this);
3206 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3207 constr
->width
.ResetIfWin((wxWindow
*)this);
3208 constr
->height
.ResetIfWin((wxWindow
*)this);
3209 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3210 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3215 delete m_constraintsInvolvedIn
;
3216 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3220 void wxWindow::SetSizer(wxSizer
*sizer
)
3222 m_windowSizer
= sizer
;
3224 sizer
->SetSizerParent((wxWindow
*)this);
3231 bool wxWindow::Layout()
3233 if (GetConstraints())
3236 GetClientSize(&w
, &h
);
3237 GetConstraints()->width
.SetValue(w
);
3238 GetConstraints()->height
.SetValue(h
);
3241 // If top level (one sizer), evaluate the sizer's constraints.
3245 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3246 GetSizer()->LayoutPhase1(&noChanges
);
3247 GetSizer()->LayoutPhase2(&noChanges
);
3248 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3253 // Otherwise, evaluate child constraints
3254 ResetConstraints(); // Mark all constraints as unevaluated
3255 DoPhase(1); // Just one phase need if no sizers involved
3257 SetConstraintSizes(); // Recursively set the real window sizes
3263 // Do a phase of evaluating constraints:
3264 // the default behaviour. wxSizers may do a similar
3265 // thing, but also impose their own 'constraints'
3266 // and order the evaluation differently.
3267 bool wxWindow::LayoutPhase1(int *noChanges
)
3269 wxLayoutConstraints
*constr
= GetConstraints();
3272 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3278 bool wxWindow::LayoutPhase2(int *noChanges
)
3288 // Do a phase of evaluating child constraints
3289 bool wxWindow::DoPhase(int phase
)
3291 int noIterations
= 0;
3292 int maxIterations
= 500;
3296 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3300 wxNode
*node
= m_children
.First();
3303 wxWindow
*child
= (wxWindow
*)node
->Data();
3304 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3306 wxLayoutConstraints
*constr
= child
->GetConstraints();
3309 if (succeeded
.Member(child
))
3314 int tempNoChanges
= 0;
3315 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3316 noChanges
+= tempNoChanges
;
3319 succeeded
.Append(child
);
3324 node
= node
->Next();
3331 void wxWindow::ResetConstraints()
3333 wxLayoutConstraints
*constr
= GetConstraints();
3336 constr
->left
.SetDone(FALSE
);
3337 constr
->top
.SetDone(FALSE
);
3338 constr
->right
.SetDone(FALSE
);
3339 constr
->bottom
.SetDone(FALSE
);
3340 constr
->width
.SetDone(FALSE
);
3341 constr
->height
.SetDone(FALSE
);
3342 constr
->centreX
.SetDone(FALSE
);
3343 constr
->centreY
.SetDone(FALSE
);
3345 wxNode
*node
= m_children
.First();
3348 wxWindow
*win
= (wxWindow
*)node
->Data();
3349 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3350 win
->ResetConstraints();
3351 node
= node
->Next();
3355 // Need to distinguish between setting the 'fake' size for
3356 // windows and sizers, and setting the real values.
3357 void wxWindow::SetConstraintSizes(bool recurse
)
3359 wxLayoutConstraints
*constr
= GetConstraints();
3360 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3361 constr
->width
.GetDone() && constr
->height
.GetDone())
3363 int x
= constr
->left
.GetValue();
3364 int y
= constr
->top
.GetValue();
3365 int w
= constr
->width
.GetValue();
3366 int h
= constr
->height
.GetValue();
3368 // If we don't want to resize this window, just move it...
3369 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3370 (constr
->height
.GetRelationship() != wxAsIs
))
3372 // Calls Layout() recursively. AAAGH. How can we stop that.
3373 // Simply take Layout() out of non-top level OnSizes.
3374 SizerSetSize(x
, y
, w
, h
);
3383 char *windowClass
= this->GetClassInfo()->GetClassName();
3386 if (GetName() == "")
3387 winName
= "unnamed";
3389 winName
= GetName();
3390 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3391 (const char *)windowClass
,
3392 (const char *)winName
);
3393 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3394 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3395 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3396 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3397 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3402 wxNode
*node
= m_children
.First();
3405 wxWindow
*win
= (wxWindow
*)node
->Data();
3406 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3407 win
->SetConstraintSizes();
3408 node
= node
->Next();
3413 // This assumes that all sizers are 'on' the same
3414 // window, i.e. the parent of this window.
3415 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3417 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3418 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3422 m_sizerParent
->GetPosition(&xp
, &yp
);
3423 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3428 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3432 TransformSizerToActual(&xx
, &yy
);
3433 SetSize(xx
, yy
, w
, h
);
3436 void wxWindow::SizerMove(int x
, int y
)
3440 TransformSizerToActual(&xx
, &yy
);
3444 // Only set the size/position of the constraint (if any)
3445 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3447 wxLayoutConstraints
*constr
= GetConstraints();
3452 constr
->left
.SetValue(x
);
3453 constr
->left
.SetDone(TRUE
);
3457 constr
->top
.SetValue(y
);
3458 constr
->top
.SetDone(TRUE
);
3462 constr
->width
.SetValue(w
);
3463 constr
->width
.SetDone(TRUE
);
3467 constr
->height
.SetValue(h
);
3468 constr
->height
.SetDone(TRUE
);
3473 void wxWindow::MoveConstraint(int x
, int y
)
3475 wxLayoutConstraints
*constr
= GetConstraints();
3480 constr
->left
.SetValue(x
);
3481 constr
->left
.SetDone(TRUE
);
3485 constr
->top
.SetValue(y
);
3486 constr
->top
.SetDone(TRUE
);
3491 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3493 wxLayoutConstraints
*constr
= GetConstraints();
3496 *w
= constr
->width
.GetValue();
3497 *h
= constr
->height
.GetValue();
3503 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3505 wxLayoutConstraints
*constr
= GetConstraints();
3508 *w
= constr
->width
.GetValue();
3509 *h
= constr
->height
.GetValue();
3512 GetClientSize(w
, h
);
3515 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3517 wxLayoutConstraints
*constr
= GetConstraints();
3520 *x
= constr
->left
.GetValue();
3521 *y
= constr
->top
.GetValue();