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"
25 #if wxUSE_DRAG_AND_DROP
30 #include "wx/tooltip.h"
34 #include "wx/statusbr.h"
36 #include "wx/settings.h"
43 #include "gdk/gdkprivate.h"
44 #include "gdk/gdkkeysyms.h"
45 #include "wx/gtk/win_gtk.h"
47 //-----------------------------------------------------------------------------
48 // documentation on internals
49 //-----------------------------------------------------------------------------
52 I have been asked several times about writing some documentation about
53 the GTK port of wxWindows, especially its internal structures. Obviously,
54 you cannot understand wxGTK without knowing a little about the GTK, but
55 some more information about what the wxWindow, which is the base class
56 for all other window classes, does seems required as well.
58 What does wxWindow do? It contains the common interface for the following
59 jobs of its descendants:
61 1) Define the rudimentary behaviour common to all window classes, such as
62 resizing, intercepting user input (so as to make it possible to use these
63 events for special purposes in a derived class), window names etc.
65 2) Provide the possibility to contain and manage children, if the derived
66 class is allowed to contain children, which holds true for those window
67 classes which do not display a native GTK widget. To name them, these
68 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
69 work classes are a special case and are handled a bit differently from
70 the rest. The same holds true for the wxNotebook class.
72 3) Provide the possibility to draw into a client area of a window. This,
73 too, only holds true for classes that do not display a native GTK widget
76 4) Provide the entire mechanism for scrolling widgets. This actual inter-
77 face for this is usually in wxScrolledWindow, but the GTK implementation
80 5) A multitude of helper or extra methods for special purposes, such as
81 Drag'n'Drop, managing validators etc.
83 Normally one might expect, that one wxWindows window would always correspond
84 to one GTK widget. Under GTK, there is no such allround widget that has all
85 the functionality. Moreover, the GTK defines a client area as a different
86 widget from the actual widget you are handling. Last but not least some
87 special classes (e.g. wxFrame) handle different categories of widgets and
88 still have the possibility to draw something in the client area.
89 It was therefore required to write a special purpose GTK widget, that would
90 represent a client area in the sense of wxWindows capable to do the jobs
91 2), 3) and 4). I have written this class and it resides in win_gtk.c of
94 All windows must have a widget, with which they interact with other under-
95 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
96 thw wxWindow class has a member variable called m_widget which holds a
97 pointer to this widget. When the window class represents a GTK native widget,
98 this is (in most cases) the only GTK widget the class manages. E.g. the
99 wxStatitText class handles only a GtkLabel widget a pointer to which you
100 can find in m_widget (defined in wxWindow)
102 When the class has a client area for drawing into and for containing children
103 it has to handle the client area widget (of the type GtkMyFixed, defined in
104 win_gtk.c), but there could be any number of widgets, handled by a class
105 The common rule for all windows is only, that the widget that interacts with
106 the rest of GTK must be referenced in m_widget and all other widgets must be
107 children of this widget on the GTK level. The top-most widget, which also
108 represents the client area, must be in the m_wxwindow field and must be of
111 As I said, the window classes that display a GTK native widget only have
112 one widget, so in the case of e.g. the wxButton class m_widget holds a
113 pointer to a GtkButton widget. But windows with client areas (for drawing
114 and children) have a m_widget field that is a pointer to a GtkScrolled-
115 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
116 one is (in the GTK sense) a child of the GtkScrolledWindow.
118 If the m_wxwindow field is set, then all input to this widget is inter-
119 cepted and sent to the wxWindows class. If not, all input to the widget
120 that gets pointed to by m_widget gets intercepted and sent to the class.
124 //-------------------------------------------------------------------------
125 // conditional compilation
126 //-------------------------------------------------------------------------
128 #if (GTK_MINOR_VERSION == 1)
129 #if (GTK_MICRO_VERSION >= 5)
130 #define NEW_GTK_SCROLL_CODE
134 //-----------------------------------------------------------------------------
136 //-----------------------------------------------------------------------------
140 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
141 GdkEvent
*WXUNUSED(event
),
144 printf( "FOCUS NOW AT: " );
151 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
159 char *s
= new char[tmp
.Length()+1];
161 strcpy( s
, WXSTRINGCAST tmp
);
163 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
164 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
169 //-----------------------------------------------------------------------------
171 //-----------------------------------------------------------------------------
173 extern wxList wxPendingDelete
;
174 extern bool g_blockEventsOnDrag
;
175 extern bool g_blockEventsOnScroll
;
176 static bool g_capturing
= FALSE
;
177 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
179 // hack: we need something to pass to gtk_menu_popup, so we store the time of
180 // the last click here
181 static guint32 gs_timeLastClick
= 0;
183 //-----------------------------------------------------------------------------
184 // "expose_event" (of m_wxwindow, not of m_widget)
185 //-----------------------------------------------------------------------------
187 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
189 if (!win
->HasVMT()) return;
191 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
193 gdk_event
->area
.width
,
194 gdk_event
->area
.height
);
196 if (gdk_event
->count
> 0) return;
199 printf( "OnExpose from " );
200 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
201 printf( win->GetClassInfo()->GetClassName() );
205 wxPaintEvent
event( win
->GetId() );
206 event
.SetEventObject( win
);
207 win
->GetEventHandler()->ProcessEvent( event
);
209 win
->m_updateRegion
.Clear();
212 //-----------------------------------------------------------------------------
213 // "draw" (of m_wxwindow, not of m_widget)
214 //-----------------------------------------------------------------------------
216 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
218 if (!win
->HasVMT()) return;
220 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
222 wxPaintEvent
event( win
->GetId() );
223 event
.SetEventObject( win
);
224 win
->GetEventHandler()->ProcessEvent( event
);
226 win
->m_updateRegion
.Clear();
229 //-----------------------------------------------------------------------------
230 // "key_press_event" from any window
231 //-----------------------------------------------------------------------------
233 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
235 if (!win
->HasVMT()) return FALSE
;
236 if (g_blockEventsOnDrag
) return FALSE
;
239 printf( "OnKeyPress from " );
240 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
241 printf( win->GetClassInfo()->GetClassName() );
246 switch (gdk_event
->keyval
)
248 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
249 case GDK_ISO_Left_Tab
:
251 case GDK_Tab
: key_code
= WXK_TAB
; break;
252 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
253 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
254 case GDK_Return
: key_code
= WXK_RETURN
; break;
255 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
256 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
257 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
258 case GDK_Delete
: key_code
= WXK_DELETE
; break;
259 case GDK_Home
: key_code
= WXK_HOME
; break;
260 case GDK_Left
: key_code
= WXK_LEFT
; break;
261 case GDK_Up
: key_code
= WXK_UP
; break;
262 case GDK_Right
: key_code
= WXK_RIGHT
; break;
263 case GDK_Down
: key_code
= WXK_DOWN
; break;
264 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
265 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
266 case GDK_Next
: key_code
= WXK_NEXT
; break;
267 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
268 case GDK_End
: key_code
= WXK_END
; break;
269 case GDK_Begin
: key_code
= WXK_HOME
; break;
270 case GDK_Select
: key_code
= WXK_SELECT
; break;
271 case GDK_Print
: key_code
= WXK_PRINT
; break;
272 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
273 case GDK_Insert
: key_code
= WXK_INSERT
; break;
274 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
275 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
276 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
277 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
278 case GDK_KP_Up
: key_code
= WXK_UP
; break;
279 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
280 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
281 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
282 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
283 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
284 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
285 case GDK_KP_End
: key_code
= WXK_END
; break;
286 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
287 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
288 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
289 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
290 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
291 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
292 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
293 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
294 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
295 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
296 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
297 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
298 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
299 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
300 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
301 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
302 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
303 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
304 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
305 case GDK_F1
: key_code
= WXK_F1
; break;
306 case GDK_F2
: key_code
= WXK_F2
; break;
307 case GDK_F3
: key_code
= WXK_F3
; break;
308 case GDK_F4
: key_code
= WXK_F4
; break;
309 case GDK_F5
: key_code
= WXK_F5
; break;
310 case GDK_F6
: key_code
= WXK_F6
; break;
311 case GDK_F7
: key_code
= WXK_F7
; break;
312 case GDK_F8
: key_code
= WXK_F8
; break;
313 case GDK_F9
: key_code
= WXK_F9
; break;
314 case GDK_F10
: key_code
= WXK_F10
; break;
315 case GDK_F11
: key_code
= WXK_F11
; break;
316 case GDK_F12
: key_code
= WXK_F12
; break;
319 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
320 key_code
= gdk_event
->keyval
;
324 if (!key_code
) return FALSE
;
326 wxKeyEvent
event( wxEVT_KEY_DOWN
);
327 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
328 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
329 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
330 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
331 event
.m_keyCode
= key_code
;
334 event
.SetEventObject( win
);
336 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
340 wxWindow
*ancestor
= win
;
343 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
346 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
347 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
350 ancestor
= ancestor
->GetParent();
354 // win is a control: tab can be propagated up
356 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
357 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
359 wxNavigationKeyEvent new_event
;
360 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
361 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
362 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
363 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
364 new_event
.SetCurrentFocus( win
);
365 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
369 (gdk_event
->keyval
== GDK_Escape
) )
371 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
372 new_event
.SetEventObject( win
);
373 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
377 Damn, I forgot why this didn't work, but it didn't work.
379 // win is a panel: up can be propagated to the panel
380 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
381 (gdk_event->keyval == GDK_Up))
383 win->m_parent->SetFocus();
387 // win is a panel: left/right can be propagated to the panel
388 if ((!ret) && (win->m_wxwindow) &&
389 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
390 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
392 wxNavigationKeyEvent new_event;
393 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
394 new_event.SetCurrentFocus( win );
395 ret = win->GetEventHandler()->ProcessEvent( new_event );
401 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
407 //-----------------------------------------------------------------------------
408 // "key_release_event" from any window
409 //-----------------------------------------------------------------------------
411 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
413 if (!win
->HasVMT()) return FALSE
;
414 if (g_blockEventsOnDrag
) return FALSE
;
417 printf( "OnKeyRelease from " );
418 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
419 printf( win->GetClassInfo()->GetClassName() );
424 switch (gdk_event
->keyval
)
426 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
427 case GDK_ISO_Left_Tab
:
429 case GDK_Tab
: key_code
= WXK_TAB
; break;
430 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
431 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
432 case GDK_Return
: key_code
= WXK_RETURN
; break;
433 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
434 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
435 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
436 case GDK_Delete
: key_code
= WXK_DELETE
; break;
437 case GDK_Home
: key_code
= WXK_HOME
; break;
438 case GDK_Left
: key_code
= WXK_LEFT
; break;
439 case GDK_Up
: key_code
= WXK_UP
; break;
440 case GDK_Right
: key_code
= WXK_RIGHT
; break;
441 case GDK_Down
: key_code
= WXK_DOWN
; break;
442 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
443 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
444 case GDK_Next
: key_code
= WXK_NEXT
; break;
445 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
446 case GDK_End
: key_code
= WXK_END
; break;
447 case GDK_Begin
: key_code
= WXK_HOME
; break;
448 case GDK_Select
: key_code
= WXK_SELECT
; break;
449 case GDK_Print
: key_code
= WXK_PRINT
; break;
450 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
451 case GDK_Insert
: key_code
= WXK_INSERT
; break;
452 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
453 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
454 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
455 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
456 case GDK_KP_Up
: key_code
= WXK_UP
; break;
457 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
458 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
459 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
460 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
461 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
462 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
463 case GDK_KP_End
: key_code
= WXK_END
; break;
464 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
465 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
466 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
467 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
468 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
469 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
470 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
471 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
472 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
473 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
474 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
475 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
476 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
477 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
478 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
479 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
480 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
481 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
482 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
483 case GDK_F1
: key_code
= WXK_F1
; break;
484 case GDK_F2
: key_code
= WXK_F2
; break;
485 case GDK_F3
: key_code
= WXK_F3
; break;
486 case GDK_F4
: key_code
= WXK_F4
; break;
487 case GDK_F5
: key_code
= WXK_F5
; break;
488 case GDK_F6
: key_code
= WXK_F6
; break;
489 case GDK_F7
: key_code
= WXK_F7
; break;
490 case GDK_F8
: key_code
= WXK_F8
; break;
491 case GDK_F9
: key_code
= WXK_F9
; break;
492 case GDK_F10
: key_code
= WXK_F10
; break;
493 case GDK_F11
: key_code
= WXK_F11
; break;
494 case GDK_F12
: key_code
= WXK_F12
; break;
497 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
498 key_code
= gdk_event
->keyval
;
502 if (!key_code
) return FALSE
;
504 wxKeyEvent
event( wxEVT_KEY_UP
);
505 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
506 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
507 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
508 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
509 event
.m_keyCode
= key_code
;
512 event
.SetEventObject( win
);
514 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
518 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
524 //-----------------------------------------------------------------------------
525 // "button_press_event"
526 //-----------------------------------------------------------------------------
528 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
530 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
532 if (g_blockEventsOnDrag
) return TRUE
;
533 if (g_blockEventsOnScroll
) return TRUE
;
537 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
539 gtk_widget_grab_focus (win
->m_wxwindow
);
542 printf( "GrabFocus from " );
543 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
544 printf( win->GetClassInfo()->GetClassName() );
551 if (!win
->HasVMT()) return TRUE
;
554 printf( "OnButtonPress from " );
555 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
556 printf( win->GetClassInfo()->GetClassName() );
560 wxEventType event_type
= wxEVT_LEFT_DOWN
;
562 if (gdk_event
->button
== 1)
564 switch (gdk_event
->type
)
566 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
567 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
571 else if (gdk_event
->button
== 2)
573 switch (gdk_event
->type
)
575 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
576 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
580 else if (gdk_event
->button
== 3)
582 switch (gdk_event
->type
)
584 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
585 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
590 wxMouseEvent
event( event_type
);
591 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
592 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
593 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
594 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
595 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
596 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
597 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
599 event
.m_x
= (long)gdk_event
->x
;
600 event
.m_y
= (long)gdk_event
->y
;
602 // Some control don't have their own X window and thus cannot get
607 wxNode
*node
= win
->GetChildren().First();
610 wxWindow
*child
= (wxWindow
*)node
->Data();
612 if (child
->m_isStaticBox
)
614 // wxStaticBox is transparent in the box itself
617 int xx1
= child
->m_x
;
618 int yy1
= child
->m_y
;
619 int xx2
= child
->m_x
+ child
->m_width
;
620 int yy2
= child
->m_x
+ child
->m_height
;
623 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
625 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
627 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
629 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
632 event
.m_x
-= child
->m_x
;
633 event
.m_y
-= child
->m_y
;
640 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
641 (child
->m_x
<= event
.m_x
) &&
642 (child
->m_y
<= event
.m_y
) &&
643 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
644 (child
->m_y
+child
->m_height
>= event
.m_y
))
647 event
.m_x
-= child
->m_x
;
648 event
.m_y
-= child
->m_y
;
656 wxPoint
pt(win
->GetClientAreaOrigin());
660 event
.SetEventObject( win
);
662 gs_timeLastClick
= gdk_event
->time
;
664 if (win
->GetEventHandler()->ProcessEvent( event
))
665 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
670 //-----------------------------------------------------------------------------
671 // "button_release_event"
672 //-----------------------------------------------------------------------------
674 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
676 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
678 if (g_blockEventsOnDrag
) return TRUE
;
679 if (g_blockEventsOnScroll
) return TRUE
;
681 if (!win
->HasVMT()) return TRUE
;
684 printf( "OnButtonRelease from " );
685 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
686 printf( win->GetClassInfo()->GetClassName() );
690 wxEventType event_type
= wxEVT_NULL
;
692 switch (gdk_event
->button
)
694 case 1: event_type
= wxEVT_LEFT_UP
; break;
695 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
696 case 3: event_type
= wxEVT_RIGHT_UP
; break;
699 wxMouseEvent
event( event_type
);
700 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
701 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
702 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
703 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
704 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
705 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
706 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
707 event
.m_x
= (long)gdk_event
->x
;
708 event
.m_y
= (long)gdk_event
->y
;
710 // Some control don't have their own X window and thus cannot get
715 wxNode
*node
= win
->GetChildren().First();
718 wxWindow
*child
= (wxWindow
*)node
->Data();
720 if (child
->m_isStaticBox
)
722 // wxStaticBox is transparent in the box itself
725 int xx1
= child
->m_x
;
726 int yy1
= child
->m_y
;
727 int xx2
= child
->m_x
+ child
->m_width
;
728 int yy2
= child
->m_x
+ child
->m_height
;
731 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
733 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
735 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
737 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
740 event
.m_x
-= child
->m_x
;
741 event
.m_y
-= child
->m_y
;
748 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
749 (child
->m_x
<= event
.m_x
) &&
750 (child
->m_y
<= event
.m_y
) &&
751 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
752 (child
->m_y
+child
->m_height
>= event
.m_y
))
755 event
.m_x
-= child
->m_x
;
756 event
.m_y
-= child
->m_y
;
764 wxPoint
pt(win
->GetClientAreaOrigin());
768 event
.SetEventObject( win
);
770 if (win
->GetEventHandler()->ProcessEvent( event
))
771 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
776 //-----------------------------------------------------------------------------
777 // "motion_notify_event"
778 //-----------------------------------------------------------------------------
780 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
782 if (gdk_event
->is_hint
)
786 GdkModifierType state
;
787 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
790 gdk_event
->state
= state
;
793 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
795 if (g_blockEventsOnDrag
) return TRUE
;
796 if (g_blockEventsOnScroll
) return TRUE
;
798 if (!win
->HasVMT()) return TRUE
;
801 printf( "OnMotion from " );
802 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
803 printf( win->GetClassInfo()->GetClassName() );
807 wxMouseEvent
event( wxEVT_MOTION
);
808 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
809 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
810 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
811 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
812 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
813 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
814 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
816 event
.m_x
= (long)gdk_event
->x
;
817 event
.m_y
= (long)gdk_event
->y
;
819 // Some control don't have their own X window and thus cannot get
824 wxNode
*node
= win
->GetChildren().First();
827 wxWindow
*child
= (wxWindow
*)node
->Data();
829 if (child
->m_isStaticBox
)
831 // wxStaticBox is transparent in the box itself
834 int xx1
= child
->m_x
;
835 int yy1
= child
->m_y
;
836 int xx2
= child
->m_x
+ child
->m_width
;
837 int yy2
= child
->m_x
+ child
->m_height
;
840 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
842 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
844 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
846 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
849 event
.m_x
-= child
->m_x
;
850 event
.m_y
-= child
->m_y
;
857 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
858 (child
->m_x
<= event
.m_x
) &&
859 (child
->m_y
<= event
.m_y
) &&
860 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
861 (child
->m_y
+child
->m_height
>= event
.m_y
))
864 event
.m_x
-= child
->m_x
;
865 event
.m_y
-= child
->m_y
;
873 wxPoint
pt(win
->GetClientAreaOrigin());
877 event
.SetEventObject( win
);
879 if (win
->GetEventHandler()->ProcessEvent( event
))
880 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
885 //-----------------------------------------------------------------------------
887 //-----------------------------------------------------------------------------
889 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
891 if (g_blockEventsOnDrag
) return TRUE
;
897 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
899 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
901 printf( "SetFocus flag from " );
902 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
903 printf( win->GetClassInfo()->GetClassName() );
909 if (!win
->HasVMT()) return TRUE
;
912 printf( "OnSetFocus from " );
913 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
914 printf( win->GetClassInfo()->GetClassName() );
916 printf( WXSTRINGCAST win->GetLabel() );
920 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
921 event
.SetEventObject( win
);
923 if (win
->GetEventHandler()->ProcessEvent( event
))
924 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
929 //-----------------------------------------------------------------------------
931 //-----------------------------------------------------------------------------
933 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
935 if (g_blockEventsOnDrag
) return TRUE
;
938 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
939 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
942 if (!win
->HasVMT()) return TRUE
;
945 printf( "OnKillFocus from " );
946 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
947 printf( win->GetClassInfo()->GetClassName() );
951 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
952 event
.SetEventObject( win
);
954 if (win
->GetEventHandler()->ProcessEvent( event
))
955 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
960 //-----------------------------------------------------------------------------
961 // "enter_notify_event"
962 //-----------------------------------------------------------------------------
964 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
966 if (g_blockEventsOnDrag
) return TRUE
;
968 if ((widget
->window
) && (win
->m_cursor
))
969 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
971 if (widget
->window
!= gdk_event
->window
) return TRUE
;
973 if (!win
->HasVMT()) return TRUE
;
976 printf( "OnEnter from " );
977 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
978 printf( win->GetClassInfo()->GetClassName() );
982 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
983 event
.SetEventObject( win
);
987 GdkModifierType state
= (GdkModifierType
)0;
989 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
991 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
992 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
993 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
994 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
995 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
996 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
997 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1000 event
.m_y
= (long)y
;
1002 wxPoint
pt(win
->GetClientAreaOrigin());
1006 if (win
->GetEventHandler()->ProcessEvent( event
))
1007 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1012 //-----------------------------------------------------------------------------
1013 // "leave_notify_event"
1014 //-----------------------------------------------------------------------------
1016 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1018 if (g_blockEventsOnDrag
) return TRUE
;
1020 if ((widget
->window
) && (win
->m_cursor
))
1021 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1023 if (widget
->window
!= gdk_event
->window
) return TRUE
;
1025 if (!win
->HasVMT()) return TRUE
;
1028 printf( "OnLeave from " );
1029 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1030 printf( win->GetClassInfo()->GetClassName() );
1034 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1035 event
.SetEventObject( win
);
1039 GdkModifierType state
= (GdkModifierType
)0;
1041 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1043 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1044 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1045 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1046 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1047 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1048 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1049 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1051 event
.m_x
= (long)x
;
1052 event
.m_y
= (long)y
;
1054 wxPoint
pt(win
->GetClientAreaOrigin());
1058 if (win
->GetEventHandler()->ProcessEvent( event
))
1059 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1064 //-----------------------------------------------------------------------------
1065 // "value_changed" from m_vAdjust
1066 //-----------------------------------------------------------------------------
1068 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1070 if (g_blockEventsOnDrag
) return;
1073 printf( "OnVScroll from " );
1074 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1075 printf( win->GetClassInfo()->GetClassName() );
1079 if (!win
->HasVMT()) return;
1081 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1082 if (fabs(diff
) < 0.2) return;
1083 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1085 wxEventType command
= wxEVT_NULL
;
1087 float line_step
= win
->m_vAdjust
->step_increment
;
1088 float page_step
= win
->m_vAdjust
->page_increment
;
1090 if (win
->m_isScrolling
)
1092 command
= wxEVT_SCROLL_THUMBTRACK
;
1096 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1097 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1098 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1099 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1100 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1101 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1102 else command
= wxEVT_SCROLL_THUMBTRACK
;
1105 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1107 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1108 event
.SetEventObject( win
);
1109 win
->GetEventHandler()->ProcessEvent( event
);
1112 //-----------------------------------------------------------------------------
1113 // "value_changed" from m_hAdjust
1114 //-----------------------------------------------------------------------------
1116 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1118 if (g_blockEventsOnDrag
) return;
1121 printf( "OnHScroll from " );
1122 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1123 printf( win->GetClassInfo()->GetClassName() );
1127 if (!win
->HasVMT()) return;
1129 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1130 if (fabs(diff
) < 0.2) return;
1131 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1133 wxEventType command
= wxEVT_NULL
;
1135 float line_step
= win
->m_hAdjust
->step_increment
;
1136 float page_step
= win
->m_hAdjust
->page_increment
;
1138 if (win
->m_isScrolling
)
1140 command
= wxEVT_SCROLL_THUMBTRACK
;
1144 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1145 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1146 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1147 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1148 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1149 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1150 else command
= wxEVT_SCROLL_THUMBTRACK
;
1153 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1155 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1156 event
.SetEventObject( win
);
1157 win
->GetEventHandler()->ProcessEvent( event
);
1160 //-----------------------------------------------------------------------------
1161 // "changed" from m_vAdjust
1162 //-----------------------------------------------------------------------------
1164 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1166 if (g_blockEventsOnDrag
) return;
1169 printf( "OnVScroll change from " );
1170 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1171 printf( win->GetClassInfo()->GetClassName() );
1175 if (!win
->HasVMT()) return;
1177 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1178 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1180 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1181 event
.SetEventObject( win
);
1182 win
->GetEventHandler()->ProcessEvent( event
);
1185 //-----------------------------------------------------------------------------
1186 // "changed" from m_hAdjust
1187 //-----------------------------------------------------------------------------
1189 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1191 if (g_blockEventsOnDrag
) return;
1194 printf( "OnHScroll change from " );
1195 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1196 printf( win->GetClassInfo()->GetClassName() );
1200 if (!win
->HasVMT()) return;
1202 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1203 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1205 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1206 event
.SetEventObject( win
);
1207 win
->GetEventHandler()->ProcessEvent( event
);
1210 //-----------------------------------------------------------------------------
1211 // "button_press_event" from scrollbar
1212 //-----------------------------------------------------------------------------
1214 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1215 GdkEventButton
*WXUNUSED(gdk_event
),
1218 // don't test here as we can release the mouse while being over
1219 // a different window then the slider
1221 // if (gdk_event->window != widget->slider) return FALSE;
1223 win
->m_isScrolling
= TRUE
;
1224 g_blockEventsOnScroll
= TRUE
;
1229 //-----------------------------------------------------------------------------
1230 // "button_release_event" from scrollbar
1231 //-----------------------------------------------------------------------------
1233 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1234 GdkEventButton
*WXUNUSED(gdk_event
),
1238 // don't test here as we can release the mouse while being over
1239 // a different window then the slider
1241 // if (gdk_event->window != widget->slider) return FALSE;
1243 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1245 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1246 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1248 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1250 win
->m_isScrolling
= FALSE
;
1251 g_blockEventsOnScroll
= FALSE
;
1256 //-----------------------------------------------------------------------------
1257 // InsertChild for wxWindow.
1258 //-----------------------------------------------------------------------------
1260 /* Callback for wxWindow. This very strange beast has to be used because
1261 * C++ has no virtual methods in a constructor. We have to emulate a
1262 * virtual function here as wxNotebook requires a different way to insert
1263 * a child in it. I had opted for creating a wxNotebookPage window class
1264 * which would have made this superfluous (such in the MDI window system),
1265 * but no-one was listening to me... */
1267 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1269 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1270 GTK_WIDGET(child
->m_widget
),
1274 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1278 if (wxIS_KIND_OF(parent
,wxFrame
))
1280 parent
->m_sizeSet
= FALSE
;
1283 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1285 /* we now allow a window to get the focus as long as it
1286 doesn't have any children. */
1287 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1291 //-----------------------------------------------------------------------------
1293 //-----------------------------------------------------------------------------
1295 wxWindow
* wxGetActiveWindow()
1297 return g_focusWindow
;
1300 //-----------------------------------------------------------------------------
1302 //-----------------------------------------------------------------------------
1304 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1306 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1307 EVT_SIZE(wxWindow::OnSize
)
1308 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1309 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1310 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1313 void wxWindow::Init()
1317 m_widget
= (GtkWidget
*) NULL
;
1318 m_wxwindow
= (GtkWidget
*) NULL
;
1319 m_parent
= (wxWindow
*) NULL
;
1320 m_children
.DeleteContents( FALSE
);
1333 m_eventHandler
= this;
1334 m_windowValidator
= (wxValidator
*) NULL
;
1338 m_cursor
= (wxCursor
*) NULL
;
1339 m_font
= *wxSWISS_FONT
;
1341 m_windowName
= "noname";
1343 m_constraints
= (wxLayoutConstraints
*) NULL
;
1344 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1345 m_windowSizer
= (wxSizer
*) NULL
;
1346 m_sizerParent
= (wxWindow
*) NULL
;
1347 m_autoLayout
= FALSE
;
1351 m_needParent
= TRUE
;
1353 m_hasScrolling
= FALSE
;
1354 m_isScrolling
= FALSE
;
1355 m_hAdjust
= (GtkAdjustment
*) NULL
;
1356 m_vAdjust
= (GtkAdjustment
*) NULL
;
1357 m_oldHorizontalPos
= 0.0;
1358 m_oldVerticalPos
= 0.0;
1363 #if wxUSE_DRAG_AND_DROP
1364 m_dropTarget
= (wxDropTarget
*) NULL
;
1367 m_scrollGC
= (GdkGC
*) NULL
;
1368 m_widgetStyle
= (GtkStyle
*) NULL
;
1370 m_insertCallback
= wxInsertChildInWindow
;
1372 m_clientObject
= (wxClientData
*) NULL
;
1373 m_clientData
= NULL
;
1375 m_isStaticBox
= FALSE
;
1376 m_acceptsFocus
= FALSE
;
1379 m_toolTip
= (wxToolTip
*) NULL
;
1380 #endif // wxUSE_TOOLTIPS
1383 wxWindow::wxWindow()
1388 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1389 const wxPoint
&pos
, const wxSize
&size
,
1390 long style
, const wxString
&name
)
1394 Create( parent
, id
, pos
, size
, style
, name
);
1397 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1398 const wxPoint
&pos
, const wxSize
&size
,
1399 long style
, const wxString
&name
)
1401 wxASSERT_MSG( m_isWindow
, "Init() must have been called before!" );
1403 PreCreation( parent
, id
, pos
, size
, style
, name
);
1405 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1406 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1409 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1412 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1415 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1416 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1419 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1420 scroll_class
->scrollbar_spacing
= 0;
1422 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1424 m_oldHorizontalPos
= 0.0;
1425 m_oldVerticalPos
= 0.0;
1427 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1428 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1430 m_wxwindow
= gtk_myfixed_new();
1433 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1436 #ifdef NEW_GTK_SCROLL_CODE
1437 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1438 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1440 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1441 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1445 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1448 if (m_windowStyle
& wxRAISED_BORDER
)
1450 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1452 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1454 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1458 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1461 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1463 /* we now allow a window to get the focus as long as it
1464 doesn't have any children. */
1465 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1466 m_acceptsFocus
= FALSE
;
1470 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1471 m_acceptsFocus
= TRUE
;
1474 // shut the viewport up
1475 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1476 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1478 // I _really_ don't want scrollbars in the beginning
1479 m_vAdjust
->lower
= 0.0;
1480 m_vAdjust
->upper
= 1.0;
1481 m_vAdjust
->value
= 0.0;
1482 m_vAdjust
->step_increment
= 1.0;
1483 m_vAdjust
->page_increment
= 1.0;
1484 m_vAdjust
->page_size
= 5.0;
1485 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1486 m_hAdjust
->lower
= 0.0;
1487 m_hAdjust
->upper
= 1.0;
1488 m_hAdjust
->value
= 0.0;
1489 m_hAdjust
->step_increment
= 1.0;
1490 m_hAdjust
->page_increment
= 1.0;
1491 m_hAdjust
->page_size
= 5.0;
1492 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1494 // these handlers block mouse events to any window during scrolling
1495 // such as motion events and prevent GTK and wxWindows from fighting
1496 // over where the slider should be
1498 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1499 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1501 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1502 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1504 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1505 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1507 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1508 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1510 // these handers het notified when screen updates are required either when
1511 // scrolling or when the window size (and therefore scrollbar configuration)
1514 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1515 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1516 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1517 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1519 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1520 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1521 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1522 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1524 gtk_widget_show( m_wxwindow
);
1526 if (m_parent
) m_parent
->AddChild( this );
1528 (m_parent
->m_insertCallback
)( m_parent
, this );
1537 wxWindow::~wxWindow()
1541 #if wxUSE_DRAG_AND_DROP
1544 delete m_dropTarget
;
1545 m_dropTarget
= (wxDropTarget
*) NULL
;
1553 m_toolTip
= (wxToolTip
*) NULL
;
1555 #endif // wxUSE_TOOLTIPS
1557 if (m_widget
) Show( FALSE
);
1561 if (m_parent
) m_parent
->RemoveChild( this );
1563 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1565 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1567 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1569 if (m_widget
) gtk_widget_destroy( m_widget
);
1571 if (m_cursor
) delete m_cursor
;
1573 DeleteRelatedConstraints();
1576 /* This removes any dangling pointers to this window
1577 * in other windows' constraintsInvolvedIn lists. */
1578 UnsetConstraints(m_constraints
);
1579 delete m_constraints
;
1580 m_constraints
= (wxLayoutConstraints
*) NULL
;
1585 delete m_windowSizer
;
1586 m_windowSizer
= (wxSizer
*) NULL
;
1588 /* If this is a child of a sizer, remove self from parent */
1589 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1591 /* Just in case the window has been Closed, but
1592 * we're then deleting immediately: don't leave
1593 * dangling pointers. */
1594 wxPendingDelete
.DeleteObject(this);
1596 /* Just in case we've loaded a top-level window via
1597 * wxWindow::LoadNativeDialog but we weren't a dialog
1599 wxTopLevelWindows
.DeleteObject(this);
1601 if (m_windowValidator
) delete m_windowValidator
;
1603 if (m_clientObject
) delete m_clientObject
;
1606 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1607 const wxPoint
&pos
, const wxSize
&size
,
1608 long style
, const wxString
&name
)
1610 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1612 m_widget
= (GtkWidget
*) NULL
;
1613 m_wxwindow
= (GtkWidget
*) NULL
;
1616 m_children
.DeleteContents( FALSE
);
1619 if (m_width
== -1) m_width
= 20;
1621 if (m_height
== -1) m_height
= 20;
1626 if (!m_needParent
) /* some reasonable defaults */
1630 m_x
= (gdk_screen_width () - m_width
) / 2;
1631 if (m_x
< 10) m_x
= 10;
1635 m_y
= (gdk_screen_height () - m_height
) / 2;
1636 if (m_y
< 10) m_y
= 10;
1647 m_eventHandler
= this;
1649 m_windowId
= id
== -1 ? wxNewId() : id
;
1653 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1654 m_font
= *wxSWISS_FONT
;
1655 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1656 m_foregroundColour
= *wxBLACK
;
1657 m_windowStyle
= style
;
1658 m_windowName
= name
;
1660 m_constraints
= (wxLayoutConstraints
*) NULL
;
1661 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1662 m_windowSizer
= (wxSizer
*) NULL
;
1663 m_sizerParent
= (wxWindow
*) NULL
;
1664 m_autoLayout
= FALSE
;
1666 m_hasScrolling
= FALSE
;
1667 m_isScrolling
= FALSE
;
1668 m_hAdjust
= (GtkAdjustment
*) NULL
;
1669 m_vAdjust
= (GtkAdjustment
*) NULL
;
1670 m_oldHorizontalPos
= 0.0;
1671 m_oldVerticalPos
= 0.0;
1676 #if wxUSE_DRAG_AND_DROP
1677 m_dropTarget
= (wxDropTarget
*) NULL
;
1680 m_windowValidator
= (wxValidator
*) NULL
;
1681 m_scrollGC
= (GdkGC
*) NULL
;
1682 m_widgetStyle
= (GtkStyle
*) NULL
;
1684 m_clientObject
= (wxClientData
*)NULL
;
1685 m_clientData
= NULL
;
1687 m_isStaticBox
= FALSE
;
1690 m_toolTip
= (wxToolTip
*) NULL
;
1691 #endif // wxUSE_TOOLTIPS
1694 void wxWindow::PostCreation()
1696 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1700 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1701 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1703 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1704 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1707 ConnectWidget( GetConnectWidget() );
1709 /* we force the creation of wxFrame and wxDialog in the respective code */
1710 if (m_parent
) gtk_widget_realize( m_widget
);
1712 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1714 SetCursor( *wxSTANDARD_CURSOR
);
1719 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1721 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1722 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1724 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1725 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1727 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1728 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1730 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1731 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1733 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1734 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1736 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1737 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1739 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1740 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1742 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1743 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1745 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1746 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1749 bool wxWindow::HasVMT()
1754 bool wxWindow::Close( bool force
)
1756 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1758 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1759 event
.SetEventObject(this);
1760 event
.SetCanVeto(!force
);
1762 /* return FALSE if window wasn't closed because the application vetoed the
1764 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1767 bool wxWindow::Destroy()
1769 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1776 bool wxWindow::DestroyChildren()
1779 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1782 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1785 if (m_children
.Member(child
)) delete node
;
1791 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1793 // are we to set fonts here ?
1796 wxPoint
wxWindow::GetClientAreaOrigin() const
1798 return wxPoint(0,0);
1801 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1803 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1805 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1811 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1813 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1814 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1816 if (m_resizing
) return; /* I don't like recursions */
1819 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1821 /* don't set the size for children of wxNotebook, just take the values. */
1829 int old_width
= m_width
;
1830 int old_height
= m_height
;
1832 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1834 if (x
!= -1) m_x
= x
;
1835 if (y
!= -1) m_y
= y
;
1836 if (width
!= -1) m_width
= width
;
1837 if (height
!= -1) m_height
= height
;
1847 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1849 if (width
== -1) m_width
= 80;
1852 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1854 if (height
== -1) m_height
= 26;
1857 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1858 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1859 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1860 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1862 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1864 /* the default button has a border around it */
1867 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1868 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border
);
1870 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1874 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1875 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1877 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1878 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1884 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1885 event
.SetEventObject( this );
1886 GetEventHandler()->ProcessEvent( event
);
1891 void wxWindow::OnInternalIdle()
1896 void wxWindow::GetSize( int *width
, int *height
) const
1898 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1900 if (width
) (*width
) = m_width
;
1901 if (height
) (*height
) = m_height
;
1904 void wxWindow::DoSetClientSize( int width
, int height
)
1906 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1910 SetSize( width
, height
);
1917 if (!m_hasScrolling
)
1919 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1921 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1922 (m_windowStyle
& wxSUNKEN_BORDER
))
1924 dw
+= 2 * window_class
->xthickness
;
1925 dh
+= 2 * window_class
->ythickness
;
1930 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1931 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1933 #ifdef NEW_GTK_SCROLL_CODE
1934 GtkWidget
*viewport
= scroll_window
->child
;
1936 GtkWidget
*viewport
= scroll_window
->viewport
;
1939 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1941 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1942 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1944 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1945 (m_windowStyle
& wxSUNKEN_BORDER
))
1947 dw
+= 2 * viewport_class
->xthickness
;
1948 dh
+= 2 * viewport_class
->ythickness
;
1951 if (scroll_window
->vscrollbar_visible
)
1953 dw
+= vscrollbar
->allocation
.width
;
1954 dw
+= scroll_class
->scrollbar_spacing
;
1957 if (scroll_window
->hscrollbar_visible
)
1959 dh
+= hscrollbar
->allocation
.height
;
1960 dw
+= scroll_class
->scrollbar_spacing
;
1964 SetSize( width
+dw
, height
+dh
);
1968 void wxWindow::GetClientSize( int *width
, int *height
) const
1970 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1974 if (width
) (*width
) = m_width
;
1975 if (height
) (*height
) = m_height
;
1982 if (!m_hasScrolling
)
1984 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1986 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1987 (m_windowStyle
& wxSUNKEN_BORDER
))
1989 dw
+= 2 * window_class
->xthickness
;
1990 dh
+= 2 * window_class
->ythickness
;
1995 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1996 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1998 #ifdef NEW_GTK_SCROLL_CODE
1999 GtkWidget
*viewport
= scroll_window
->child
;
2001 GtkWidget
*viewport
= scroll_window
->viewport
;
2004 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2006 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2007 (m_windowStyle
& wxSUNKEN_BORDER
))
2009 dw
+= 2 * viewport_class
->xthickness
;
2010 dh
+= 2 * viewport_class
->ythickness
;
2013 if (scroll_window
->vscrollbar_visible
)
2015 // dw += vscrollbar->allocation.width;
2016 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
2017 dw
+= scroll_class
->scrollbar_spacing
;
2020 if (scroll_window
->hscrollbar_visible
)
2022 // dh += hscrollbar->allocation.height;
2024 dh
+= scroll_class
->scrollbar_spacing
;
2028 if (width
) (*width
) = m_width
- dw
;
2029 if (height
) (*height
) = m_height
- dh
;
2033 void wxWindow::GetPosition( int *x
, int *y
) const
2035 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2041 void wxWindow::ClientToScreen( int *x
, int *y
)
2043 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2045 GdkWindow
*source
= (GdkWindow
*) NULL
;
2047 source
= m_wxwindow
->window
;
2049 source
= m_widget
->window
;
2053 gdk_window_get_origin( source
, &org_x
, &org_y
);
2057 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2059 org_x
+= m_widget
->allocation
.x
;
2060 org_y
+= m_widget
->allocation
.y
;
2064 wxPoint
pt(GetClientAreaOrigin());
2072 void wxWindow::ScreenToClient( int *x
, int *y
)
2074 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2076 GdkWindow
*source
= (GdkWindow
*) NULL
;
2078 source
= m_wxwindow
->window
;
2080 source
= m_widget
->window
;
2084 gdk_window_get_origin( source
, &org_x
, &org_y
);
2088 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2090 org_x
+= m_widget
->allocation
.x
;
2091 org_y
+= m_widget
->allocation
.y
;
2095 wxPoint
pt(GetClientAreaOrigin());
2103 void wxWindow::Centre( int direction
)
2105 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2114 m_parent
->GetSize( &p_w
, &p_h
);
2115 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2116 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2120 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2121 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2127 void wxWindow::Fit()
2129 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2133 wxNode
*node
= m_children
.First();
2136 wxWindow
*win
= (wxWindow
*)node
->Data();
2138 win
->GetPosition(&wx
, &wy
);
2139 win
->GetSize(&ww
, &wh
);
2140 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2141 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2143 node
= node
->Next();
2146 SetClientSize(maxX
+ 7, maxY
+ 14);
2149 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2151 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2159 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2161 // if (GetAutoLayout()) Layout();
2164 bool wxWindow::Show( bool show
)
2166 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2168 if (show
== m_isShown
) return TRUE
;
2171 gtk_widget_show( m_widget
);
2173 gtk_widget_hide( m_widget
);
2180 void wxWindow::Enable( bool enable
)
2182 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2184 m_isEnabled
= enable
;
2186 gtk_widget_set_sensitive( m_widget
, enable
);
2187 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2190 int wxWindow::GetCharHeight() const
2192 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2194 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2196 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2198 return font
->ascent
+ font
->descent
;
2201 int wxWindow::GetCharWidth() const
2203 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2205 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2207 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2209 return gdk_string_width( font
, "H" );
2212 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2213 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2215 wxFont fontToUse
= m_font
;
2216 if (theFont
) fontToUse
= *theFont
;
2218 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2220 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2221 if (x
) (*x
) = gdk_string_width( font
, string
);
2222 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2223 if (descent
) (*descent
) = font
->descent
;
2224 if (externalLeading
) (*externalLeading
) = 0; // ??
2227 void wxWindow::MakeModal( bool modal
)
2231 // Disable all other windows
2232 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2234 wxNode
*node
= wxTopLevelWindows
.First();
2237 wxWindow
*win
= (wxWindow
*)node
->Data();
2238 if (win
!= this) win
->Enable(!modal
);
2240 node
= node
->Next();
2245 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2247 event
.SetEventType( wxEVT_CHAR
);
2249 if (!GetEventHandler()->ProcessEvent( event
))
2255 void wxWindow::SetFocus()
2257 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2259 GtkWidget
*connect_widget
= GetConnectWidget();
2262 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2264 gtk_widget_grab_focus (connect_widget
);
2266 else if (GTK_IS_CONTAINER(connect_widget
))
2268 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2276 wxWindow
*wxWindow::FindFocus()
2278 return g_focusWindow
;
2281 bool wxWindow::AcceptsFocus() const
2283 return IsEnabled() && IsShown() && m_acceptsFocus
;
2286 void wxWindow::AddChild( wxWindow
*child
)
2288 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2289 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2291 m_children
.Append( child
);
2294 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2296 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2298 wxWindow
*oldParent
= GetParent();
2300 if (oldParent
) oldParent
->RemoveChild( this );
2302 gtk_widget_unparent( m_widget
);
2306 newParent
->AddChild( this );
2307 (newParent
->m_insertCallback
)( newParent
, this );
2313 void wxWindow::RemoveChild( wxWindow
*child
)
2315 m_children
.DeleteObject( child
);
2316 child
->m_parent
= (wxWindow
*) NULL
;
2319 void wxWindow::SetReturnCode( int retCode
)
2321 m_retCode
= retCode
;
2324 int wxWindow::GetReturnCode()
2329 void wxWindow::Raise()
2331 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2333 if (m_widget
) gdk_window_raise( m_widget
->window
);
2336 void wxWindow::Lower()
2338 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2340 if (m_widget
) gdk_window_lower( m_widget
->window
);
2343 wxEvtHandler
*wxWindow::GetEventHandler() const
2345 return m_eventHandler
;
2348 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2350 m_eventHandler
= handler
;
2353 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2355 handler
->SetNextHandler(GetEventHandler());
2356 SetEventHandler(handler
);
2359 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2361 if (GetEventHandler())
2363 wxEvtHandler
*handlerA
= GetEventHandler();
2364 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2365 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2366 SetEventHandler(handlerB
);
2370 return (wxEvtHandler
*) NULL
;
2376 return (wxEvtHandler
*) NULL
;
2379 wxValidator
*wxWindow::GetValidator()
2381 return m_windowValidator
;
2384 void wxWindow::SetValidator( const wxValidator
& validator
)
2386 if (m_windowValidator
) delete m_windowValidator
;
2387 m_windowValidator
= validator
.Clone();
2388 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2391 void wxWindow::SetClientObject( wxClientData
*data
)
2393 if (m_clientObject
) delete m_clientObject
;
2394 m_clientObject
= data
;
2397 wxClientData
*wxWindow::GetClientObject()
2399 return m_clientObject
;
2402 void wxWindow::SetClientData( void *data
)
2404 m_clientData
= data
;
2407 void *wxWindow::GetClientData()
2409 return m_clientData
;
2412 bool wxWindow::IsBeingDeleted()
2417 void wxWindow::SetId( wxWindowID id
)
2422 wxWindowID
wxWindow::GetId() const
2427 void wxWindow::SetCursor( const wxCursor
&cursor
)
2429 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2433 if (cursor
== *m_cursor
) return;
2438 *m_cursor
= *wxSTANDARD_CURSOR
;
2441 if ((m_widget
) && (m_widget
->window
))
2442 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2444 if ((m_wxwindow
) && (m_wxwindow
->window
))
2445 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2448 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2453 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2455 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2457 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2461 gdk_window_clear_area( m_wxwindow
->window
,
2463 rect
->width
, rect
->height
);
2467 gdk_window_clear( m_wxwindow
->window
);
2474 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2476 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2480 GdkRectangle gdk_rect
;
2481 gdk_rect
.x
= rect
->x
;
2482 gdk_rect
.y
= rect
->y
;
2483 gdk_rect
.width
= rect
->width
;
2484 gdk_rect
.height
= rect
->height
;
2487 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2489 gtk_widget_draw( m_widget
, &gdk_rect
);
2493 wxRegion
wxWindow::GetUpdateRegion() const
2495 return m_updateRegion
;
2498 bool wxWindow::IsExposed( int x
, int y
) const
2500 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2503 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2505 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2508 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2510 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2513 bool wxWindow::IsExposed( const wxRect
& rect
) const
2515 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2518 void wxWindow::Clear()
2520 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2522 if (m_wxwindow
&& m_wxwindow
->window
)
2524 gdk_window_clear( m_wxwindow
->window
);
2529 void wxWindow::SetToolTip( const wxString
&tip
)
2533 m_toolTip
->SetTip( tip
);
2537 SetToolTip( new wxToolTip( tip
) );
2540 // setting empty tooltip text does not remove the tooltip any more for
2541 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2544 void wxWindow::SetToolTip( wxToolTip
*tip
)
2548 m_toolTip
->SetTip( (char*) NULL
);
2555 m_toolTip
->Apply( this );
2558 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2560 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2562 #endif // wxUSE_TOOLTIPS
2564 wxColour
wxWindow::GetBackgroundColour() const
2566 return m_backgroundColour
;
2569 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2571 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2573 if (m_backgroundColour
== colour
) return;
2575 m_backgroundColour
= colour
;
2576 if (!m_backgroundColour
.Ok()) return;
2578 if (m_wxwindow
&& m_wxwindow
->window
)
2580 /* wxMSW doesn't clear the window here. I don't do that
2581 either to provide compatibility. call Clear() to do
2584 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2585 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2588 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2590 if (sysbg
.Red() == colour
.Red() &&
2591 sysbg
.Green() == colour
.Green() &&
2592 sysbg
.Blue() == colour
.Blue())
2594 m_backgroundColour
= wxNullColour
;
2596 m_backgroundColour
= sysbg
;
2604 wxColour
wxWindow::GetForegroundColour() const
2606 return m_foregroundColour
;
2609 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2611 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2613 if (m_foregroundColour
== colour
) return;
2615 m_foregroundColour
= colour
;
2616 if (!m_foregroundColour
.Ok()) return;
2618 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2619 if (sysbg
.Red() == colour
.Red() &&
2620 sysbg
.Green() == colour
.Green() &&
2621 sysbg
.Blue() == colour
.Blue())
2623 m_backgroundColour
= wxNullColour
;
2625 m_backgroundColour
= sysbg
;
2633 GtkStyle
*wxWindow::GetWidgetStyle()
2635 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2639 gtk_widget_get_style( m_widget
) );
2641 return m_widgetStyle
;
2644 void wxWindow::SetWidgetStyle()
2646 GtkStyle
*style
= GetWidgetStyle();
2648 gdk_font_unref( style
->font
);
2649 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2651 if (m_foregroundColour
.Ok())
2653 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2654 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2655 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2656 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2659 if (m_backgroundColour
.Ok())
2661 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2662 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2663 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2664 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2665 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2666 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2667 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2668 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2669 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2673 void wxWindow::ApplyWidgetStyle()
2677 bool wxWindow::Validate()
2679 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2681 wxNode
*node
= m_children
.First();
2684 wxWindow
*child
= (wxWindow
*)node
->Data();
2685 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2689 node
= node
->Next();
2694 bool wxWindow::TransferDataToWindow()
2696 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2698 wxNode
*node
= m_children
.First();
2701 wxWindow
*child
= (wxWindow
*)node
->Data();
2702 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2703 !child
->GetValidator()->TransferToWindow() )
2705 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2708 node
= node
->Next();
2713 bool wxWindow::TransferDataFromWindow()
2715 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2717 wxNode
*node
= m_children
.First();
2720 wxWindow
*child
= (wxWindow
*)node
->Data();
2721 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2725 node
= node
->Next();
2730 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2732 m_acceleratorTable
= accel
;
2735 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2737 TransferDataToWindow();
2740 void wxWindow::InitDialog()
2742 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2744 wxInitDialogEvent
event(GetId());
2745 event
.SetEventObject( this );
2746 GetEventHandler()->ProcessEvent(event
);
2749 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2751 menu
->SetInvokingWindow( win
);
2752 wxNode
*node
= menu
->GetItems().First();
2755 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2756 if (menuitem
->IsSubMenu())
2758 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2760 node
= node
->Next();
2764 static gint gs_pop_x
= 0;
2765 static gint gs_pop_y
= 0;
2767 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2769 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2774 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2776 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2778 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2780 SetInvokingWindow( menu
, this );
2788 GTK_MENU(menu
->m_menu
),
2789 (GtkWidget
*) NULL
, // parent menu shell
2790 (GtkWidget
*) NULL
, // parent menu item
2791 (GtkMenuPositionFunc
) pop_pos_callback
,
2792 (gpointer
) this, // client data
2793 0, // button used to activate it
2794 0 //gs_timeLastClick // the time of activation
2799 #if wxUSE_DRAG_AND_DROP
2801 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2803 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2805 GtkWidget
*dnd_widget
= GetConnectWidget();
2807 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2809 if (m_dropTarget
) delete m_dropTarget
;
2810 m_dropTarget
= dropTarget
;
2812 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2815 wxDropTarget
*wxWindow::GetDropTarget() const
2817 return m_dropTarget
;
2822 GtkWidget
* wxWindow::GetConnectWidget()
2824 GtkWidget
*connect_widget
= m_widget
;
2825 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2827 return connect_widget
;
2830 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2832 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2833 return (window
== m_widget
->window
);
2836 void wxWindow::SetFont( const wxFont
&font
)
2838 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2840 if (m_font
== font
) return;
2842 if (((wxFont
*)&font
)->Ok())
2845 m_font
= *wxSWISS_FONT
;
2847 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2848 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2849 sysbg
.Green() == m_backgroundColour
.Green() &&
2850 sysbg
.Blue() == m_backgroundColour
.Blue())
2852 m_backgroundColour
= wxNullColour
;
2854 m_backgroundColour
= sysbg
;
2862 void wxWindow::SetWindowStyleFlag( long flag
)
2864 m_windowStyle
= flag
;
2867 long wxWindow::GetWindowStyleFlag() const
2869 return m_windowStyle
;
2872 void wxWindow::CaptureMouse()
2874 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2876 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2878 GtkWidget
*connect_widget
= GetConnectWidget();
2879 gtk_grab_add( connect_widget
);
2880 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2882 (GDK_BUTTON_PRESS_MASK
|
2883 GDK_BUTTON_RELEASE_MASK
|
2884 GDK_POINTER_MOTION_MASK
),
2891 void wxWindow::ReleaseMouse()
2893 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2895 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2897 GtkWidget
*connect_widget
= GetConnectWidget();
2898 gtk_grab_remove( connect_widget
);
2899 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2900 g_capturing
= FALSE
;
2903 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2907 wxString
wxWindow::GetTitle() const
2909 return (wxString
&)m_windowName
;
2912 wxString
wxWindow::GetLabel() const
2917 void wxWindow::SetName( const wxString
&name
)
2919 m_windowName
= name
;
2922 wxString
wxWindow::GetName() const
2924 return (wxString
&)m_windowName
;
2927 bool wxWindow::IsShown() const
2932 bool wxWindow::IsRetained()
2937 wxWindow
*wxWindow::FindWindow( long id
)
2939 if (id
== m_windowId
) return this;
2940 wxNode
*node
= m_children
.First();
2943 wxWindow
*child
= (wxWindow
*)node
->Data();
2944 wxWindow
*res
= child
->FindWindow( id
);
2945 if (res
) return res
;
2946 node
= node
->Next();
2948 return (wxWindow
*) NULL
;
2951 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2953 if (name
== m_windowName
) return this;
2954 wxNode
*node
= m_children
.First();
2957 wxWindow
*child
= (wxWindow
*)node
->Data();
2958 wxWindow
*res
= child
->FindWindow( name
);
2959 if (res
) return res
;
2960 node
= node
->Next();
2962 return (wxWindow
*) NULL
;
2965 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2966 int range
, bool refresh
)
2968 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2970 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2972 m_hasScrolling
= TRUE
;
2974 if (orient
== wxHORIZONTAL
)
2976 float fpos
= (float)pos
;
2977 float frange
= (float)range
;
2978 float fthumb
= (float)thumbVisible
;
2979 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2980 if (fpos
< 0.0) fpos
= 0.0;
2982 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2983 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2985 SetScrollPos( orient
, pos
, refresh
);
2989 m_oldHorizontalPos
= fpos
;
2991 m_hAdjust
->lower
= 0.0;
2992 m_hAdjust
->upper
= frange
;
2993 m_hAdjust
->value
= fpos
;
2994 m_hAdjust
->step_increment
= 1.0;
2995 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2996 m_hAdjust
->page_size
= fthumb
;
3000 float fpos
= (float)pos
;
3001 float frange
= (float)range
;
3002 float fthumb
= (float)thumbVisible
;
3003 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3004 if (fpos
< 0.0) fpos
= 0.0;
3006 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3007 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3009 SetScrollPos( orient
, pos
, refresh
);
3013 m_oldVerticalPos
= fpos
;
3015 m_vAdjust
->lower
= 0.0;
3016 m_vAdjust
->upper
= frange
;
3017 m_vAdjust
->value
= fpos
;
3018 m_vAdjust
->step_increment
= 1.0;
3019 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3020 m_vAdjust
->page_size
= fthumb
;
3023 if (m_wxwindow
->window
)
3025 if (orient
== wxHORIZONTAL
)
3026 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3028 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3030 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3034 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3036 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3038 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3040 if (orient
== wxHORIZONTAL
)
3042 float fpos
= (float)pos
;
3043 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3044 if (fpos
< 0.0) fpos
= 0.0;
3045 m_oldHorizontalPos
= fpos
;
3047 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3048 m_hAdjust
->value
= fpos
;
3052 float fpos
= (float)pos
;
3053 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3054 if (fpos
< 0.0) fpos
= 0.0;
3055 m_oldVerticalPos
= fpos
;
3057 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3058 m_vAdjust
->value
= fpos
;
3063 if (m_wxwindow
->window
)
3065 if (orient
== wxHORIZONTAL
)
3066 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3068 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3073 int wxWindow::GetScrollThumb( int orient
) const
3075 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3077 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3079 if (orient
== wxHORIZONTAL
)
3080 return (int)(m_hAdjust
->page_size
+0.5);
3082 return (int)(m_vAdjust
->page_size
+0.5);
3085 int wxWindow::GetScrollPos( int orient
) const
3087 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3089 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3091 if (orient
== wxHORIZONTAL
)
3092 return (int)(m_hAdjust
->value
+0.5);
3094 return (int)(m_vAdjust
->value
+0.5);
3097 int wxWindow::GetScrollRange( int orient
) const
3099 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3101 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3103 if (orient
== wxHORIZONTAL
)
3104 return (int)(m_hAdjust
->upper
+0.5);
3106 return (int)(m_vAdjust
->upper
+0.5);
3109 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3111 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3113 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3117 GetClientSize( &cw
, &ch
);
3119 int w
= cw
- abs(dx
);
3120 int h
= ch
- abs(dy
);
3121 if ((h
< 0) || (w
< 0))
3128 if (dx
< 0) s_x
= -dx
;
3129 if (dy
< 0) s_y
= -dy
;
3132 if (dx
> 0) d_x
= dx
;
3133 if (dy
> 0) d_y
= dy
;
3137 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3138 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3141 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3142 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3145 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3146 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3147 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3148 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3150 Refresh( TRUE
, &rect
);
3153 //-------------------------------------------------------------------------------------
3155 //-------------------------------------------------------------------------------------
3157 wxLayoutConstraints
*wxWindow::GetConstraints() const
3159 return m_constraints
;
3162 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3166 UnsetConstraints(m_constraints
);
3167 delete m_constraints
;
3169 m_constraints
= constraints
;
3172 // Make sure other windows know they're part of a 'meaningful relationship'
3173 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3174 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3175 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3176 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3177 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3178 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3179 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3180 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3181 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3182 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3183 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3184 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3185 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3186 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3187 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3188 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3194 void wxWindow::SetAutoLayout( bool autoLayout
)
3196 m_autoLayout
= autoLayout
;
3199 bool wxWindow::GetAutoLayout() const
3201 return m_autoLayout
;
3204 wxSizer
*wxWindow::GetSizer() const
3206 return m_windowSizer
;
3209 void wxWindow::SetSizerParent( wxWindow
*win
)
3211 m_sizerParent
= win
;
3214 wxWindow
*wxWindow::GetSizerParent() const
3216 return m_sizerParent
;
3219 // This removes any dangling pointers to this window
3220 // in other windows' constraintsInvolvedIn lists.
3221 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3225 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3226 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3227 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3228 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3229 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3230 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3231 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3232 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3233 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3234 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3235 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3236 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3237 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3238 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3239 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3240 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3244 // Back-pointer to other windows we're involved with, so if we delete
3245 // this window, we must delete any constraints we're involved with.
3246 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3248 if (!m_constraintsInvolvedIn
)
3249 m_constraintsInvolvedIn
= new wxList
;
3250 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3251 m_constraintsInvolvedIn
->Append(otherWin
);
3254 // REMOVE back-pointer to other windows we're involved with.
3255 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3257 if (m_constraintsInvolvedIn
)
3258 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3261 // Reset any constraints that mention this window
3262 void wxWindow::DeleteRelatedConstraints()
3264 if (m_constraintsInvolvedIn
)
3266 wxNode
*node
= m_constraintsInvolvedIn
->First();
3269 wxWindow
*win
= (wxWindow
*)node
->Data();
3270 wxNode
*next
= node
->Next();
3271 wxLayoutConstraints
*constr
= win
->GetConstraints();
3273 // Reset any constraints involving this window
3276 constr
->left
.ResetIfWin((wxWindow
*)this);
3277 constr
->top
.ResetIfWin((wxWindow
*)this);
3278 constr
->right
.ResetIfWin((wxWindow
*)this);
3279 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3280 constr
->width
.ResetIfWin((wxWindow
*)this);
3281 constr
->height
.ResetIfWin((wxWindow
*)this);
3282 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3283 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3288 delete m_constraintsInvolvedIn
;
3289 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3293 void wxWindow::SetSizer(wxSizer
*sizer
)
3295 m_windowSizer
= sizer
;
3297 sizer
->SetSizerParent((wxWindow
*)this);
3304 bool wxWindow::Layout()
3306 if (GetConstraints())
3309 GetClientSize(&w
, &h
);
3310 GetConstraints()->width
.SetValue(w
);
3311 GetConstraints()->height
.SetValue(h
);
3314 // If top level (one sizer), evaluate the sizer's constraints.
3318 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3319 GetSizer()->LayoutPhase1(&noChanges
);
3320 GetSizer()->LayoutPhase2(&noChanges
);
3321 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3326 // Otherwise, evaluate child constraints
3327 ResetConstraints(); // Mark all constraints as unevaluated
3328 DoPhase(1); // Just one phase need if no sizers involved
3330 SetConstraintSizes(); // Recursively set the real window sizes
3336 // Do a phase of evaluating constraints:
3337 // the default behaviour. wxSizers may do a similar
3338 // thing, but also impose their own 'constraints'
3339 // and order the evaluation differently.
3340 bool wxWindow::LayoutPhase1(int *noChanges
)
3342 wxLayoutConstraints
*constr
= GetConstraints();
3345 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3351 bool wxWindow::LayoutPhase2(int *noChanges
)
3361 // Do a phase of evaluating child constraints
3362 bool wxWindow::DoPhase(int phase
)
3364 int noIterations
= 0;
3365 int maxIterations
= 500;
3369 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3373 wxNode
*node
= m_children
.First();
3376 wxWindow
*child
= (wxWindow
*)node
->Data();
3377 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3379 wxLayoutConstraints
*constr
= child
->GetConstraints();
3382 if (succeeded
.Member(child
))
3387 int tempNoChanges
= 0;
3388 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3389 noChanges
+= tempNoChanges
;
3392 succeeded
.Append(child
);
3397 node
= node
->Next();
3404 void wxWindow::ResetConstraints()
3406 wxLayoutConstraints
*constr
= GetConstraints();
3409 constr
->left
.SetDone(FALSE
);
3410 constr
->top
.SetDone(FALSE
);
3411 constr
->right
.SetDone(FALSE
);
3412 constr
->bottom
.SetDone(FALSE
);
3413 constr
->width
.SetDone(FALSE
);
3414 constr
->height
.SetDone(FALSE
);
3415 constr
->centreX
.SetDone(FALSE
);
3416 constr
->centreY
.SetDone(FALSE
);
3418 wxNode
*node
= m_children
.First();
3421 wxWindow
*win
= (wxWindow
*)node
->Data();
3422 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3423 win
->ResetConstraints();
3424 node
= node
->Next();
3428 // Need to distinguish between setting the 'fake' size for
3429 // windows and sizers, and setting the real values.
3430 void wxWindow::SetConstraintSizes(bool recurse
)
3432 wxLayoutConstraints
*constr
= GetConstraints();
3433 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3434 constr
->width
.GetDone() && constr
->height
.GetDone())
3436 int x
= constr
->left
.GetValue();
3437 int y
= constr
->top
.GetValue();
3438 int w
= constr
->width
.GetValue();
3439 int h
= constr
->height
.GetValue();
3441 // If we don't want to resize this window, just move it...
3442 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3443 (constr
->height
.GetRelationship() != wxAsIs
))
3445 // Calls Layout() recursively. AAAGH. How can we stop that.
3446 // Simply take Layout() out of non-top level OnSizes.
3447 SizerSetSize(x
, y
, w
, h
);
3456 char *windowClass
= this->GetClassInfo()->GetClassName();
3459 if (GetName() == "")
3460 winName
= "unnamed";
3462 winName
= GetName();
3463 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3464 (const char *)windowClass
,
3465 (const char *)winName
);
3466 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3467 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3468 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3469 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3470 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3475 wxNode
*node
= m_children
.First();
3478 wxWindow
*win
= (wxWindow
*)node
->Data();
3479 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3480 win
->SetConstraintSizes();
3481 node
= node
->Next();
3486 // This assumes that all sizers are 'on' the same
3487 // window, i.e. the parent of this window.
3488 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3490 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3491 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3495 m_sizerParent
->GetPosition(&xp
, &yp
);
3496 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3501 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3505 TransformSizerToActual(&xx
, &yy
);
3506 SetSize(xx
, yy
, w
, h
);
3509 void wxWindow::SizerMove(int x
, int y
)
3513 TransformSizerToActual(&xx
, &yy
);
3517 // Only set the size/position of the constraint (if any)
3518 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3520 wxLayoutConstraints
*constr
= GetConstraints();
3525 constr
->left
.SetValue(x
);
3526 constr
->left
.SetDone(TRUE
);
3530 constr
->top
.SetValue(y
);
3531 constr
->top
.SetDone(TRUE
);
3535 constr
->width
.SetValue(w
);
3536 constr
->width
.SetDone(TRUE
);
3540 constr
->height
.SetValue(h
);
3541 constr
->height
.SetDone(TRUE
);
3546 void wxWindow::MoveConstraint(int x
, int y
)
3548 wxLayoutConstraints
*constr
= GetConstraints();
3553 constr
->left
.SetValue(x
);
3554 constr
->left
.SetDone(TRUE
);
3558 constr
->top
.SetValue(y
);
3559 constr
->top
.SetDone(TRUE
);
3564 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3566 wxLayoutConstraints
*constr
= GetConstraints();
3569 *w
= constr
->width
.GetValue();
3570 *h
= constr
->height
.GetValue();
3576 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3578 wxLayoutConstraints
*constr
= GetConstraints();
3581 *w
= constr
->width
.GetValue();
3582 *h
= constr
->height
.GetValue();
3585 GetClientSize(w
, h
);
3588 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3590 wxLayoutConstraints
*constr
= GetConstraints();
3593 *x
= constr
->left
.GetValue();
3594 *y
= constr
->top
.GetValue();