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 > 0)
129 #define NEW_GTK_SCROLL_CODE
132 //-----------------------------------------------------------------------------
134 //-----------------------------------------------------------------------------
138 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
139 GdkEvent
*WXUNUSED(event
),
142 printf( "FOCUS NOW AT: " );
149 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
157 char *s
= new char[tmp
.Length()+1];
159 strcpy( s
, WXSTRINGCAST tmp
);
161 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
162 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
167 //-----------------------------------------------------------------------------
169 //-----------------------------------------------------------------------------
171 extern wxList wxPendingDelete
;
172 extern bool g_blockEventsOnDrag
;
173 extern bool g_blockEventsOnScroll
;
174 static bool g_capturing
= FALSE
;
175 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
177 // hack: we need something to pass to gtk_menu_popup, so we store the time of
178 // the last click here
179 static guint32 gs_timeLastClick
= 0;
181 //-----------------------------------------------------------------------------
182 // "expose_event" (of m_wxwindow, not of m_widget)
183 //-----------------------------------------------------------------------------
185 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
187 if (!win
->HasVMT()) return;
189 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
191 gdk_event
->area
.width
,
192 gdk_event
->area
.height
);
194 if (gdk_event
->count
> 0) return;
197 printf( "OnExpose from " );
198 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
199 printf( win->GetClassInfo()->GetClassName() );
203 wxPaintEvent
event( win
->GetId() );
204 event
.SetEventObject( win
);
205 win
->GetEventHandler()->ProcessEvent( event
);
207 win
->m_updateRegion
.Clear();
210 //-----------------------------------------------------------------------------
211 // "draw" (of m_wxwindow, not of m_widget)
212 //-----------------------------------------------------------------------------
214 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
216 if (!win
->HasVMT()) return;
218 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
220 wxPaintEvent
event( win
->GetId() );
221 event
.SetEventObject( win
);
222 win
->GetEventHandler()->ProcessEvent( event
);
224 win
->m_updateRegion
.Clear();
227 //-----------------------------------------------------------------------------
228 // "key_press_event" from any window
229 //-----------------------------------------------------------------------------
231 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
233 if (!win
->HasVMT()) return FALSE
;
234 if (g_blockEventsOnDrag
) return FALSE
;
237 printf( "OnKeyPress from " );
238 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
239 printf( win->GetClassInfo()->GetClassName() );
244 switch (gdk_event
->keyval
)
246 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
247 case GDK_ISO_Left_Tab
:
249 case GDK_Tab
: key_code
= WXK_TAB
; break;
250 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
251 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
252 case GDK_Return
: key_code
= WXK_RETURN
; break;
253 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
254 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
255 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
256 case GDK_Delete
: key_code
= WXK_DELETE
; break;
257 case GDK_Home
: key_code
= WXK_HOME
; break;
258 case GDK_Left
: key_code
= WXK_LEFT
; break;
259 case GDK_Up
: key_code
= WXK_UP
; break;
260 case GDK_Right
: key_code
= WXK_RIGHT
; break;
261 case GDK_Down
: key_code
= WXK_DOWN
; break;
262 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
263 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
264 case GDK_Next
: key_code
= WXK_NEXT
; break;
265 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
266 case GDK_End
: key_code
= WXK_END
; break;
267 case GDK_Begin
: key_code
= WXK_HOME
; break;
268 case GDK_Select
: key_code
= WXK_SELECT
; break;
269 case GDK_Print
: key_code
= WXK_PRINT
; break;
270 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
271 case GDK_Insert
: key_code
= WXK_INSERT
; break;
272 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
273 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
274 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
275 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
276 case GDK_KP_Up
: key_code
= WXK_UP
; break;
277 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
278 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
279 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
280 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
281 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
282 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
283 case GDK_KP_End
: key_code
= WXK_END
; break;
284 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
285 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
286 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
287 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
288 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
289 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
290 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
291 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
292 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
293 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
294 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
295 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
296 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
297 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
298 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
299 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
300 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
301 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
302 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
303 case GDK_F1
: key_code
= WXK_F1
; break;
304 case GDK_F2
: key_code
= WXK_F2
; break;
305 case GDK_F3
: key_code
= WXK_F3
; break;
306 case GDK_F4
: key_code
= WXK_F4
; break;
307 case GDK_F5
: key_code
= WXK_F5
; break;
308 case GDK_F6
: key_code
= WXK_F6
; break;
309 case GDK_F7
: key_code
= WXK_F7
; break;
310 case GDK_F8
: key_code
= WXK_F8
; break;
311 case GDK_F9
: key_code
= WXK_F9
; break;
312 case GDK_F10
: key_code
= WXK_F10
; break;
313 case GDK_F11
: key_code
= WXK_F11
; break;
314 case GDK_F12
: key_code
= WXK_F12
; break;
317 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
318 key_code
= gdk_event
->keyval
;
322 if (!key_code
) return FALSE
;
324 wxKeyEvent
event( wxEVT_KEY_DOWN
);
325 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
326 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
327 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
328 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
329 event
.m_keyCode
= key_code
;
332 event
.SetEventObject( win
);
334 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
338 wxWindow
*ancestor
= win
;
341 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
344 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
345 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
348 ancestor
= ancestor
->GetParent();
352 // win is a control: tab can be propagated up
354 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
355 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
357 wxNavigationKeyEvent new_event
;
358 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
359 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
360 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
361 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
362 new_event
.SetCurrentFocus( win
);
363 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
367 (gdk_event
->keyval
== GDK_Escape
) )
369 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
370 new_event
.SetEventObject( win
);
371 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
375 Damn, I forgot why this didn't work, but it didn't work.
377 // win is a panel: up can be propagated to the panel
378 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
379 (gdk_event->keyval == GDK_Up))
381 win->m_parent->SetFocus();
385 // win is a panel: left/right can be propagated to the panel
386 if ((!ret) && (win->m_wxwindow) &&
387 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
388 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
390 wxNavigationKeyEvent new_event;
391 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
392 new_event.SetCurrentFocus( win );
393 ret = win->GetEventHandler()->ProcessEvent( new_event );
399 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
405 //-----------------------------------------------------------------------------
406 // "key_release_event" from any window
407 //-----------------------------------------------------------------------------
409 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
411 if (!win
->HasVMT()) return FALSE
;
412 if (g_blockEventsOnDrag
) return FALSE
;
415 printf( "OnKeyRelease from " );
416 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
417 printf( win->GetClassInfo()->GetClassName() );
422 switch (gdk_event
->keyval
)
424 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
425 case GDK_ISO_Left_Tab
:
427 case GDK_Tab
: key_code
= WXK_TAB
; break;
428 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
429 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
430 case GDK_Return
: key_code
= WXK_RETURN
; break;
431 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
432 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
433 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
434 case GDK_Delete
: key_code
= WXK_DELETE
; break;
435 case GDK_Home
: key_code
= WXK_HOME
; break;
436 case GDK_Left
: key_code
= WXK_LEFT
; break;
437 case GDK_Up
: key_code
= WXK_UP
; break;
438 case GDK_Right
: key_code
= WXK_RIGHT
; break;
439 case GDK_Down
: key_code
= WXK_DOWN
; break;
440 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
441 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
442 case GDK_Next
: key_code
= WXK_NEXT
; break;
443 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
444 case GDK_End
: key_code
= WXK_END
; break;
445 case GDK_Begin
: key_code
= WXK_HOME
; break;
446 case GDK_Select
: key_code
= WXK_SELECT
; break;
447 case GDK_Print
: key_code
= WXK_PRINT
; break;
448 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
449 case GDK_Insert
: key_code
= WXK_INSERT
; break;
450 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
451 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
452 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
453 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
454 case GDK_KP_Up
: key_code
= WXK_UP
; break;
455 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
456 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
457 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
458 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
459 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
460 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
461 case GDK_KP_End
: key_code
= WXK_END
; break;
462 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
463 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
464 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
465 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
466 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
467 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
468 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
469 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
470 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
471 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
472 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
473 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
474 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
475 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
476 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
477 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
478 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
479 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
480 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
481 case GDK_F1
: key_code
= WXK_F1
; break;
482 case GDK_F2
: key_code
= WXK_F2
; break;
483 case GDK_F3
: key_code
= WXK_F3
; break;
484 case GDK_F4
: key_code
= WXK_F4
; break;
485 case GDK_F5
: key_code
= WXK_F5
; break;
486 case GDK_F6
: key_code
= WXK_F6
; break;
487 case GDK_F7
: key_code
= WXK_F7
; break;
488 case GDK_F8
: key_code
= WXK_F8
; break;
489 case GDK_F9
: key_code
= WXK_F9
; break;
490 case GDK_F10
: key_code
= WXK_F10
; break;
491 case GDK_F11
: key_code
= WXK_F11
; break;
492 case GDK_F12
: key_code
= WXK_F12
; break;
495 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
496 key_code
= gdk_event
->keyval
;
500 if (!key_code
) return FALSE
;
502 wxKeyEvent
event( wxEVT_KEY_UP
);
503 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
504 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
505 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
506 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
507 event
.m_keyCode
= key_code
;
510 event
.SetEventObject( win
);
512 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
516 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
522 //-----------------------------------------------------------------------------
523 // "button_press_event"
524 //-----------------------------------------------------------------------------
526 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
528 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
530 if (g_blockEventsOnDrag
) return TRUE
;
531 if (g_blockEventsOnScroll
) return TRUE
;
535 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
537 gtk_widget_grab_focus (win
->m_wxwindow
);
540 printf( "GrabFocus from " );
541 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
542 printf( win->GetClassInfo()->GetClassName() );
549 if (!win
->HasVMT()) return TRUE
;
552 printf( "OnButtonPress from " );
553 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
554 printf( win->GetClassInfo()->GetClassName() );
558 wxEventType event_type
= wxEVT_LEFT_DOWN
;
560 if (gdk_event
->button
== 1)
562 switch (gdk_event
->type
)
564 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
565 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
569 else if (gdk_event
->button
== 2)
571 switch (gdk_event
->type
)
573 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
574 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
578 else if (gdk_event
->button
== 3)
580 switch (gdk_event
->type
)
582 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
583 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
588 wxMouseEvent
event( event_type
);
589 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
590 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
591 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
592 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
593 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
594 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
595 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
597 event
.m_x
= (long)gdk_event
->x
;
598 event
.m_y
= (long)gdk_event
->y
;
600 // Some control don't have their own X window and thus cannot get
605 wxNode
*node
= win
->GetChildren().First();
608 wxWindow
*child
= (wxWindow
*)node
->Data();
610 if (child
->m_isStaticBox
)
612 // wxStaticBox is transparent in the box itself
615 int xx1
= child
->m_x
;
616 int yy1
= child
->m_y
;
617 int xx2
= child
->m_x
+ child
->m_width
;
618 int yy2
= child
->m_x
+ child
->m_height
;
621 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
623 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
625 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
627 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
630 event
.m_x
-= child
->m_x
;
631 event
.m_y
-= child
->m_y
;
638 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
639 (child
->m_x
<= event
.m_x
) &&
640 (child
->m_y
<= event
.m_y
) &&
641 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
642 (child
->m_y
+child
->m_height
>= event
.m_y
))
645 event
.m_x
-= child
->m_x
;
646 event
.m_y
-= child
->m_y
;
654 wxPoint
pt(win
->GetClientAreaOrigin());
658 event
.SetEventObject( win
);
660 gs_timeLastClick
= gdk_event
->time
;
662 if (win
->GetEventHandler()->ProcessEvent( event
))
663 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
668 //-----------------------------------------------------------------------------
669 // "button_release_event"
670 //-----------------------------------------------------------------------------
672 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
674 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
676 if (g_blockEventsOnDrag
) return TRUE
;
677 if (g_blockEventsOnScroll
) return TRUE
;
679 if (!win
->HasVMT()) return TRUE
;
682 printf( "OnButtonRelease from " );
683 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
684 printf( win->GetClassInfo()->GetClassName() );
688 wxEventType event_type
= wxEVT_NULL
;
690 switch (gdk_event
->button
)
692 case 1: event_type
= wxEVT_LEFT_UP
; break;
693 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
694 case 3: event_type
= wxEVT_RIGHT_UP
; break;
697 wxMouseEvent
event( event_type
);
698 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
699 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
700 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
701 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
702 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
703 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
704 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
705 event
.m_x
= (long)gdk_event
->x
;
706 event
.m_y
= (long)gdk_event
->y
;
708 // Some control don't have their own X window and thus cannot get
713 wxNode
*node
= win
->GetChildren().First();
716 wxWindow
*child
= (wxWindow
*)node
->Data();
718 if (child
->m_isStaticBox
)
720 // wxStaticBox is transparent in the box itself
723 int xx1
= child
->m_x
;
724 int yy1
= child
->m_y
;
725 int xx2
= child
->m_x
+ child
->m_width
;
726 int yy2
= child
->m_x
+ child
->m_height
;
729 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
731 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
733 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
735 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
738 event
.m_x
-= child
->m_x
;
739 event
.m_y
-= child
->m_y
;
746 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
747 (child
->m_x
<= event
.m_x
) &&
748 (child
->m_y
<= event
.m_y
) &&
749 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
750 (child
->m_y
+child
->m_height
>= event
.m_y
))
753 event
.m_x
-= child
->m_x
;
754 event
.m_y
-= child
->m_y
;
762 wxPoint
pt(win
->GetClientAreaOrigin());
766 event
.SetEventObject( win
);
768 if (win
->GetEventHandler()->ProcessEvent( event
))
769 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
774 //-----------------------------------------------------------------------------
775 // "motion_notify_event"
776 //-----------------------------------------------------------------------------
778 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
780 if (gdk_event
->is_hint
)
784 GdkModifierType state
;
785 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
788 gdk_event
->state
= state
;
791 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
793 if (g_blockEventsOnDrag
) return TRUE
;
794 if (g_blockEventsOnScroll
) return TRUE
;
796 if (!win
->HasVMT()) return TRUE
;
799 printf( "OnMotion from " );
800 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
801 printf( win->GetClassInfo()->GetClassName() );
805 wxMouseEvent
event( wxEVT_MOTION
);
806 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
807 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
808 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
809 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
810 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
811 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
812 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
814 event
.m_x
= (long)gdk_event
->x
;
815 event
.m_y
= (long)gdk_event
->y
;
817 // Some control don't have their own X window and thus cannot get
822 wxNode
*node
= win
->GetChildren().First();
825 wxWindow
*child
= (wxWindow
*)node
->Data();
827 if (child
->m_isStaticBox
)
829 // wxStaticBox is transparent in the box itself
832 int xx1
= child
->m_x
;
833 int yy1
= child
->m_y
;
834 int xx2
= child
->m_x
+ child
->m_width
;
835 int yy2
= child
->m_x
+ child
->m_height
;
838 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
840 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
842 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
844 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
847 event
.m_x
-= child
->m_x
;
848 event
.m_y
-= child
->m_y
;
855 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
856 (child
->m_x
<= event
.m_x
) &&
857 (child
->m_y
<= event
.m_y
) &&
858 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
859 (child
->m_y
+child
->m_height
>= event
.m_y
))
862 event
.m_x
-= child
->m_x
;
863 event
.m_y
-= child
->m_y
;
871 wxPoint
pt(win
->GetClientAreaOrigin());
875 event
.SetEventObject( win
);
877 if (win
->GetEventHandler()->ProcessEvent( event
))
878 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
883 //-----------------------------------------------------------------------------
885 //-----------------------------------------------------------------------------
887 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
889 if (g_blockEventsOnDrag
) return TRUE
;
895 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
897 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
899 printf( "SetFocus flag from " );
900 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
901 printf( win->GetClassInfo()->GetClassName() );
907 if (!win
->HasVMT()) return TRUE
;
910 printf( "OnSetFocus from " );
911 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
912 printf( win->GetClassInfo()->GetClassName() );
914 printf( WXSTRINGCAST win->GetLabel() );
918 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
919 event
.SetEventObject( win
);
921 if (win
->GetEventHandler()->ProcessEvent( event
))
922 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
927 //-----------------------------------------------------------------------------
929 //-----------------------------------------------------------------------------
931 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
933 if (g_blockEventsOnDrag
) return TRUE
;
936 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
937 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
940 if (!win
->HasVMT()) return TRUE
;
943 printf( "OnKillFocus from " );
944 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
945 printf( win->GetClassInfo()->GetClassName() );
949 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
950 event
.SetEventObject( win
);
952 if (win
->GetEventHandler()->ProcessEvent( event
))
953 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
958 //-----------------------------------------------------------------------------
959 // "enter_notify_event"
960 //-----------------------------------------------------------------------------
962 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
964 if (g_blockEventsOnDrag
) return TRUE
;
966 if ((widget
->window
) && (win
->m_cursor
))
967 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
969 if (widget
->window
!= gdk_event
->window
) return TRUE
;
971 if (!win
->HasVMT()) return TRUE
;
974 printf( "OnEnter from " );
975 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
976 printf( win->GetClassInfo()->GetClassName() );
980 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
981 event
.SetEventObject( win
);
985 GdkModifierType state
= (GdkModifierType
)0;
987 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
989 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
990 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
991 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
992 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
993 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
994 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
995 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1000 wxPoint
pt(win
->GetClientAreaOrigin());
1004 if (win
->GetEventHandler()->ProcessEvent( event
))
1005 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1010 //-----------------------------------------------------------------------------
1011 // "leave_notify_event"
1012 //-----------------------------------------------------------------------------
1014 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1016 if (g_blockEventsOnDrag
) return TRUE
;
1018 if ((widget
->window
) && (win
->m_cursor
))
1019 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1021 if (widget
->window
!= gdk_event
->window
) return TRUE
;
1023 if (!win
->HasVMT()) return TRUE
;
1026 printf( "OnLeave from " );
1027 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1028 printf( win->GetClassInfo()->GetClassName() );
1032 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1033 event
.SetEventObject( win
);
1037 GdkModifierType state
= (GdkModifierType
)0;
1039 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1041 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1042 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1043 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1044 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1045 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1046 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1047 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1049 event
.m_x
= (long)x
;
1050 event
.m_y
= (long)y
;
1052 wxPoint
pt(win
->GetClientAreaOrigin());
1056 if (win
->GetEventHandler()->ProcessEvent( event
))
1057 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1062 //-----------------------------------------------------------------------------
1063 // "value_changed" from m_vAdjust
1064 //-----------------------------------------------------------------------------
1066 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1068 if (g_blockEventsOnDrag
) return;
1071 printf( "OnVScroll from " );
1072 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1073 printf( win->GetClassInfo()->GetClassName() );
1077 if (!win
->HasVMT()) return;
1079 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1080 if (fabs(diff
) < 0.2) return;
1081 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1083 wxEventType command
= wxEVT_NULL
;
1085 float line_step
= win
->m_vAdjust
->step_increment
;
1086 float page_step
= win
->m_vAdjust
->page_increment
;
1088 if (win
->m_isScrolling
)
1090 command
= wxEVT_SCROLL_THUMBTRACK
;
1094 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1095 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1096 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1097 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1098 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1099 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1100 else command
= wxEVT_SCROLL_THUMBTRACK
;
1103 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1105 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1106 event
.SetEventObject( win
);
1107 win
->GetEventHandler()->ProcessEvent( event
);
1110 //-----------------------------------------------------------------------------
1111 // "value_changed" from m_hAdjust
1112 //-----------------------------------------------------------------------------
1114 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1116 if (g_blockEventsOnDrag
) return;
1119 printf( "OnHScroll from " );
1120 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1121 printf( win->GetClassInfo()->GetClassName() );
1125 if (!win
->HasVMT()) return;
1127 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1128 if (fabs(diff
) < 0.2) return;
1129 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1131 wxEventType command
= wxEVT_NULL
;
1133 float line_step
= win
->m_hAdjust
->step_increment
;
1134 float page_step
= win
->m_hAdjust
->page_increment
;
1136 if (win
->m_isScrolling
)
1138 command
= wxEVT_SCROLL_THUMBTRACK
;
1142 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1143 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1144 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1145 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1146 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1147 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1148 else command
= wxEVT_SCROLL_THUMBTRACK
;
1151 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1153 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1154 event
.SetEventObject( win
);
1155 win
->GetEventHandler()->ProcessEvent( event
);
1158 //-----------------------------------------------------------------------------
1159 // "changed" from m_vAdjust
1160 //-----------------------------------------------------------------------------
1162 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1164 if (g_blockEventsOnDrag
) return;
1167 printf( "OnVScroll change from " );
1168 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1169 printf( win->GetClassInfo()->GetClassName() );
1173 if (!win
->HasVMT()) return;
1175 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1176 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1178 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1179 event
.SetEventObject( win
);
1180 win
->GetEventHandler()->ProcessEvent( event
);
1183 //-----------------------------------------------------------------------------
1184 // "changed" from m_hAdjust
1185 //-----------------------------------------------------------------------------
1187 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1189 if (g_blockEventsOnDrag
) return;
1192 printf( "OnHScroll change from " );
1193 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1194 printf( win->GetClassInfo()->GetClassName() );
1198 if (!win
->HasVMT()) return;
1200 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1201 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1203 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1204 event
.SetEventObject( win
);
1205 win
->GetEventHandler()->ProcessEvent( event
);
1208 //-----------------------------------------------------------------------------
1209 // "button_press_event" from scrollbar
1210 //-----------------------------------------------------------------------------
1212 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1213 GdkEventButton
*WXUNUSED(gdk_event
),
1216 // don't test here as we can release the mouse while being over
1217 // a different window then the slider
1219 // if (gdk_event->window != widget->slider) return FALSE;
1221 win
->m_isScrolling
= TRUE
;
1222 g_blockEventsOnScroll
= TRUE
;
1227 //-----------------------------------------------------------------------------
1228 // "button_release_event" from scrollbar
1229 //-----------------------------------------------------------------------------
1231 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1232 GdkEventButton
*WXUNUSED(gdk_event
),
1236 // don't test here as we can release the mouse while being over
1237 // a different window then the slider
1239 // if (gdk_event->window != widget->slider) return FALSE;
1241 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1243 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1244 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1246 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1248 win
->m_isScrolling
= FALSE
;
1249 g_blockEventsOnScroll
= FALSE
;
1254 //-----------------------------------------------------------------------------
1255 // InsertChild for wxWindow.
1256 //-----------------------------------------------------------------------------
1258 /* Callback for wxWindow. This very strange beast has to be used because
1259 * C++ has no virtual methods in a constructor. We have to emulate a
1260 * virtual function here as wxNotebook requires a different way to insert
1261 * a child in it. I had opted for creating a wxNotebookPage window class
1262 * which would have made this superfluous (such in the MDI window system),
1263 * but no-one was listening to me... */
1265 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1267 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1268 GTK_WIDGET(child
->m_widget
),
1272 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1276 if (wxIS_KIND_OF(parent
,wxFrame
))
1278 parent
->m_sizeSet
= FALSE
;
1281 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1283 /* we now allow a window to get the focus as long as it
1284 doesn't have any children. */
1285 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1289 //-----------------------------------------------------------------------------
1291 //-----------------------------------------------------------------------------
1293 wxWindow
* wxGetActiveWindow()
1295 return g_focusWindow
;
1298 //-----------------------------------------------------------------------------
1300 //-----------------------------------------------------------------------------
1302 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1304 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1305 EVT_SIZE(wxWindow::OnSize
)
1306 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1307 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1308 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1311 void wxWindow::Init()
1315 m_widget
= (GtkWidget
*) NULL
;
1316 m_wxwindow
= (GtkWidget
*) NULL
;
1317 m_parent
= (wxWindow
*) NULL
;
1318 m_children
.DeleteContents( FALSE
);
1331 m_eventHandler
= this;
1332 m_windowValidator
= (wxValidator
*) NULL
;
1336 m_cursor
= (wxCursor
*) NULL
;
1337 m_font
= *wxSWISS_FONT
;
1339 m_windowName
= "noname";
1341 m_constraints
= (wxLayoutConstraints
*) NULL
;
1342 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1343 m_windowSizer
= (wxSizer
*) NULL
;
1344 m_sizerParent
= (wxWindow
*) NULL
;
1345 m_autoLayout
= FALSE
;
1349 m_needParent
= TRUE
;
1351 m_hasScrolling
= FALSE
;
1352 m_isScrolling
= FALSE
;
1353 m_hAdjust
= (GtkAdjustment
*) NULL
;
1354 m_vAdjust
= (GtkAdjustment
*) NULL
;
1355 m_oldHorizontalPos
= 0.0;
1356 m_oldVerticalPos
= 0.0;
1361 #if wxUSE_DRAG_AND_DROP
1362 m_dropTarget
= (wxDropTarget
*) NULL
;
1365 m_scrollGC
= (GdkGC
*) NULL
;
1366 m_widgetStyle
= (GtkStyle
*) NULL
;
1368 m_insertCallback
= wxInsertChildInWindow
;
1370 m_clientObject
= (wxClientData
*) NULL
;
1371 m_clientData
= NULL
;
1373 m_isStaticBox
= FALSE
;
1374 m_acceptsFocus
= FALSE
;
1377 m_toolTip
= (wxToolTip
*) NULL
;
1378 #endif // wxUSE_TOOLTIPS
1381 wxWindow::wxWindow()
1386 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1387 const wxPoint
&pos
, const wxSize
&size
,
1388 long style
, const wxString
&name
)
1392 Create( parent
, id
, pos
, size
, style
, name
);
1395 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1396 const wxPoint
&pos
, const wxSize
&size
,
1397 long style
, const wxString
&name
)
1399 wxASSERT_MSG( m_isWindow
, "Init() must have been called before!" );
1401 PreCreation( parent
, id
, pos
, size
, style
, name
);
1403 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1404 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1407 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1410 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1413 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1414 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1417 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1418 scroll_class
->scrollbar_spacing
= 0;
1420 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1422 m_oldHorizontalPos
= 0.0;
1423 m_oldVerticalPos
= 0.0;
1425 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1426 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1428 m_wxwindow
= gtk_myfixed_new();
1431 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1434 #ifdef NEW_GTK_SCROLL_CODE
1435 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1436 GtkViewport
*viewport
= GTK_VIEWPORT( GTK_BIN(s_window
)->child
);
1438 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1439 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1443 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1446 if (m_windowStyle
& wxRAISED_BORDER
)
1448 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1450 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1452 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1456 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1459 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1461 /* we now allow a window to get the focus as long as it
1462 doesn't have any children. */
1463 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1464 m_acceptsFocus
= FALSE
;
1468 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1469 m_acceptsFocus
= TRUE
;
1472 // shut the viewport up
1473 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1474 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1476 // I _really_ don't want scrollbars in the beginning
1477 m_vAdjust
->lower
= 0.0;
1478 m_vAdjust
->upper
= 1.0;
1479 m_vAdjust
->value
= 0.0;
1480 m_vAdjust
->step_increment
= 1.0;
1481 m_vAdjust
->page_increment
= 1.0;
1482 m_vAdjust
->page_size
= 5.0;
1483 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1484 m_hAdjust
->lower
= 0.0;
1485 m_hAdjust
->upper
= 1.0;
1486 m_hAdjust
->value
= 0.0;
1487 m_hAdjust
->step_increment
= 1.0;
1488 m_hAdjust
->page_increment
= 1.0;
1489 m_hAdjust
->page_size
= 5.0;
1490 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1492 // these handlers block mouse events to any window during scrolling
1493 // such as motion events and prevent GTK and wxWindows from fighting
1494 // over where the slider should be
1496 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1497 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1499 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1500 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1502 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1503 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1505 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1506 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1508 // these handers het notified when screen updates are required either when
1509 // scrolling or when the window size (and therefore scrollbar configuration)
1512 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1513 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1514 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1515 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1517 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1518 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1519 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1520 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1522 gtk_widget_show( m_wxwindow
);
1524 if (m_parent
) m_parent
->AddChild( this );
1526 (m_parent
->m_insertCallback
)( m_parent
, this );
1535 wxWindow::~wxWindow()
1539 #if wxUSE_DRAG_AND_DROP
1542 delete m_dropTarget
;
1543 m_dropTarget
= (wxDropTarget
*) NULL
;
1551 m_toolTip
= (wxToolTip
*) NULL
;
1553 #endif // wxUSE_TOOLTIPS
1555 if (m_widget
) Show( FALSE
);
1559 if (m_parent
) m_parent
->RemoveChild( this );
1561 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1563 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1565 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1567 if (m_widget
) gtk_widget_destroy( m_widget
);
1569 if (m_cursor
) delete m_cursor
;
1571 DeleteRelatedConstraints();
1574 /* This removes any dangling pointers to this window
1575 * in other windows' constraintsInvolvedIn lists. */
1576 UnsetConstraints(m_constraints
);
1577 delete m_constraints
;
1578 m_constraints
= (wxLayoutConstraints
*) NULL
;
1583 delete m_windowSizer
;
1584 m_windowSizer
= (wxSizer
*) NULL
;
1586 /* If this is a child of a sizer, remove self from parent */
1587 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1589 /* Just in case the window has been Closed, but
1590 * we're then deleting immediately: don't leave
1591 * dangling pointers. */
1592 wxPendingDelete
.DeleteObject(this);
1594 /* Just in case we've loaded a top-level window via
1595 * wxWindow::LoadNativeDialog but we weren't a dialog
1597 wxTopLevelWindows
.DeleteObject(this);
1599 if (m_windowValidator
) delete m_windowValidator
;
1601 if (m_clientObject
) delete m_clientObject
;
1604 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1605 const wxPoint
&pos
, const wxSize
&size
,
1606 long style
, const wxString
&name
)
1608 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1610 m_widget
= (GtkWidget
*) NULL
;
1611 m_wxwindow
= (GtkWidget
*) NULL
;
1614 m_children
.DeleteContents( FALSE
);
1617 if (m_width
== -1) m_width
= 20;
1619 if (m_height
== -1) m_height
= 20;
1624 if (!m_needParent
) /* some reasonable defaults */
1628 m_x
= (gdk_screen_width () - m_width
) / 2;
1629 if (m_x
< 10) m_x
= 10;
1633 m_y
= (gdk_screen_height () - m_height
) / 2;
1634 if (m_y
< 10) m_y
= 10;
1645 m_eventHandler
= this;
1647 m_windowId
= id
== -1 ? wxNewId() : id
;
1651 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1652 m_font
= *wxSWISS_FONT
;
1653 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1654 m_foregroundColour
= *wxBLACK
;
1655 m_windowStyle
= style
;
1656 m_windowName
= name
;
1658 m_constraints
= (wxLayoutConstraints
*) NULL
;
1659 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1660 m_windowSizer
= (wxSizer
*) NULL
;
1661 m_sizerParent
= (wxWindow
*) NULL
;
1662 m_autoLayout
= FALSE
;
1664 m_hasScrolling
= FALSE
;
1665 m_isScrolling
= FALSE
;
1666 m_hAdjust
= (GtkAdjustment
*) NULL
;
1667 m_vAdjust
= (GtkAdjustment
*) NULL
;
1668 m_oldHorizontalPos
= 0.0;
1669 m_oldVerticalPos
= 0.0;
1674 #if wxUSE_DRAG_AND_DROP
1675 m_dropTarget
= (wxDropTarget
*) NULL
;
1678 m_windowValidator
= (wxValidator
*) NULL
;
1679 m_scrollGC
= (GdkGC
*) NULL
;
1680 m_widgetStyle
= (GtkStyle
*) NULL
;
1682 m_clientObject
= (wxClientData
*)NULL
;
1683 m_clientData
= NULL
;
1685 m_isStaticBox
= FALSE
;
1688 m_toolTip
= (wxToolTip
*) NULL
;
1689 #endif // wxUSE_TOOLTIPS
1692 void wxWindow::PostCreation()
1694 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1698 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1699 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1701 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1702 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1705 ConnectWidget( GetConnectWidget() );
1707 /* we force the creation of wxFrame and wxDialog in the respective code */
1708 if (m_parent
) gtk_widget_realize( m_widget
);
1710 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1712 SetCursor( *wxSTANDARD_CURSOR
);
1717 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1719 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1720 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1722 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1723 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1725 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1726 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1728 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1729 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1731 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1732 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1734 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1735 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1737 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1738 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1740 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1741 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1743 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1744 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1747 bool wxWindow::HasVMT()
1752 bool wxWindow::Close( bool force
)
1754 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1756 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1757 event
.SetEventObject(this);
1758 event
.SetCanVeto(!force
);
1760 /* return FALSE if window wasn't closed because the application vetoed the
1762 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1765 bool wxWindow::Destroy()
1767 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1774 bool wxWindow::DestroyChildren()
1777 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1780 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1783 if (m_children
.Member(child
)) delete node
;
1789 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1791 // are we to set fonts here ?
1794 wxPoint
wxWindow::GetClientAreaOrigin() const
1796 return wxPoint(0,0);
1799 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1801 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1803 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1809 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1811 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1812 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1814 if (m_resizing
) return; /* I don't like recursions */
1817 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1819 /* don't set the size for children of wxNotebook, just take the values. */
1827 int old_width
= m_width
;
1828 int old_height
= m_height
;
1830 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1832 if (x
!= -1) m_x
= x
;
1833 if (y
!= -1) m_y
= y
;
1834 if (width
!= -1) m_width
= width
;
1835 if (height
!= -1) m_height
= height
;
1845 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1847 if (width
== -1) m_width
= 80;
1850 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1852 if (height
== -1) m_height
= 26;
1855 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1856 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1857 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1858 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1860 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1862 /* the default button has a border around it */
1865 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1866 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border
);
1868 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1872 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1873 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1875 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1876 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1882 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1883 event
.SetEventObject( this );
1884 GetEventHandler()->ProcessEvent( event
);
1889 void wxWindow::OnInternalIdle()
1894 void wxWindow::GetSize( int *width
, int *height
) const
1896 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1898 if (width
) (*width
) = m_width
;
1899 if (height
) (*height
) = m_height
;
1902 void wxWindow::DoSetClientSize( int width
, int height
)
1904 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1908 SetSize( width
, height
);
1915 if (!m_hasScrolling
)
1917 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1919 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1920 (m_windowStyle
& wxSUNKEN_BORDER
))
1922 dw
+= 2 * window_class
->xthickness
;
1923 dh
+= 2 * window_class
->ythickness
;
1928 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1929 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1931 #ifdef NEW_GTK_SCROLL_CODE
1932 GtkWidget
*viewport
= GTK_BIN(scroll_window
)->child
;
1934 GtkWidget
*viewport
= scroll_window
->viewport
;
1937 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1939 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1940 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1942 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1943 (m_windowStyle
& wxSUNKEN_BORDER
))
1945 dw
+= 2 * viewport_class
->xthickness
;
1946 dh
+= 2 * viewport_class
->ythickness
;
1949 if (scroll_window
->vscrollbar_visible
)
1951 dw
+= vscrollbar
->allocation
.width
;
1952 dw
+= scroll_class
->scrollbar_spacing
;
1955 if (scroll_window
->hscrollbar_visible
)
1957 dh
+= hscrollbar
->allocation
.height
;
1958 dw
+= scroll_class
->scrollbar_spacing
;
1962 SetSize( width
+dw
, height
+dh
);
1966 void wxWindow::GetClientSize( int *width
, int *height
) const
1968 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1972 if (width
) (*width
) = m_width
;
1973 if (height
) (*height
) = m_height
;
1980 if (!m_hasScrolling
)
1982 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1984 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1985 (m_windowStyle
& wxSUNKEN_BORDER
))
1987 dw
+= 2 * window_class
->xthickness
;
1988 dh
+= 2 * window_class
->ythickness
;
1993 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1994 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1996 #ifdef NEW_GTK_SCROLL_CODE
1997 GtkWidget
*viewport
= GTK_BIN(scroll_window
)->child
;
1999 GtkWidget
*viewport
= scroll_window
->viewport
;
2002 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2004 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2005 (m_windowStyle
& wxSUNKEN_BORDER
))
2007 dw
+= 2 * viewport_class
->xthickness
;
2008 dh
+= 2 * viewport_class
->ythickness
;
2011 if (scroll_window
->vscrollbar_visible
)
2013 // dw += vscrollbar->allocation.width;
2014 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
2015 dw
+= scroll_class
->scrollbar_spacing
;
2018 if (scroll_window
->hscrollbar_visible
)
2020 // dh += hscrollbar->allocation.height;
2022 dh
+= scroll_class
->scrollbar_spacing
;
2026 if (width
) (*width
) = m_width
- dw
;
2027 if (height
) (*height
) = m_height
- dh
;
2031 void wxWindow::GetPosition( int *x
, int *y
) const
2033 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2039 void wxWindow::ClientToScreen( int *x
, int *y
)
2041 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2043 GdkWindow
*source
= (GdkWindow
*) NULL
;
2045 source
= m_wxwindow
->window
;
2047 source
= m_widget
->window
;
2051 gdk_window_get_origin( source
, &org_x
, &org_y
);
2055 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2057 org_x
+= m_widget
->allocation
.x
;
2058 org_y
+= m_widget
->allocation
.y
;
2062 wxPoint
pt(GetClientAreaOrigin());
2070 void wxWindow::ScreenToClient( int *x
, int *y
)
2072 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2074 GdkWindow
*source
= (GdkWindow
*) NULL
;
2076 source
= m_wxwindow
->window
;
2078 source
= m_widget
->window
;
2082 gdk_window_get_origin( source
, &org_x
, &org_y
);
2086 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2088 org_x
+= m_widget
->allocation
.x
;
2089 org_y
+= m_widget
->allocation
.y
;
2093 wxPoint
pt(GetClientAreaOrigin());
2101 void wxWindow::Centre( int direction
)
2103 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2112 m_parent
->GetSize( &p_w
, &p_h
);
2113 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2114 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2118 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2119 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2125 void wxWindow::Fit()
2127 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2131 wxNode
*node
= m_children
.First();
2134 wxWindow
*win
= (wxWindow
*)node
->Data();
2136 win
->GetPosition(&wx
, &wy
);
2137 win
->GetSize(&ww
, &wh
);
2138 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2139 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2141 node
= node
->Next();
2144 SetClientSize(maxX
+ 7, maxY
+ 14);
2147 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2149 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2157 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2159 // if (GetAutoLayout()) Layout();
2162 bool wxWindow::Show( bool show
)
2164 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2166 if (show
== m_isShown
) return TRUE
;
2169 gtk_widget_show( m_widget
);
2171 gtk_widget_hide( m_widget
);
2178 void wxWindow::Enable( bool enable
)
2180 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2182 m_isEnabled
= enable
;
2184 gtk_widget_set_sensitive( m_widget
, enable
);
2185 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2188 int wxWindow::GetCharHeight() const
2190 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2192 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2194 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2196 return font
->ascent
+ font
->descent
;
2199 int wxWindow::GetCharWidth() const
2201 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2203 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2205 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2207 return gdk_string_width( font
, "H" );
2210 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2211 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2213 wxFont fontToUse
= m_font
;
2214 if (theFont
) fontToUse
= *theFont
;
2216 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2218 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2219 if (x
) (*x
) = gdk_string_width( font
, string
);
2220 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2221 if (descent
) (*descent
) = font
->descent
;
2222 if (externalLeading
) (*externalLeading
) = 0; // ??
2225 void wxWindow::MakeModal( bool modal
)
2229 // Disable all other windows
2230 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2232 wxNode
*node
= wxTopLevelWindows
.First();
2235 wxWindow
*win
= (wxWindow
*)node
->Data();
2236 if (win
!= this) win
->Enable(!modal
);
2238 node
= node
->Next();
2243 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2245 event
.SetEventType( wxEVT_CHAR
);
2247 if (!GetEventHandler()->ProcessEvent( event
))
2253 void wxWindow::SetFocus()
2255 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2257 GtkWidget
*connect_widget
= GetConnectWidget();
2260 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2262 gtk_widget_grab_focus (connect_widget
);
2264 else if (GTK_IS_CONTAINER(connect_widget
))
2266 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2274 wxWindow
*wxWindow::FindFocus()
2276 return g_focusWindow
;
2279 bool wxWindow::AcceptsFocus() const
2281 return IsEnabled() && IsShown() && m_acceptsFocus
;
2284 void wxWindow::AddChild( wxWindow
*child
)
2286 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2287 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2289 m_children
.Append( child
);
2292 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2294 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2296 wxWindow
*oldParent
= GetParent();
2298 if (oldParent
) oldParent
->RemoveChild( this );
2300 gtk_widget_unparent( m_widget
);
2304 newParent
->AddChild( this );
2305 (newParent
->m_insertCallback
)( newParent
, this );
2311 void wxWindow::RemoveChild( wxWindow
*child
)
2313 m_children
.DeleteObject( child
);
2314 child
->m_parent
= (wxWindow
*) NULL
;
2317 void wxWindow::SetReturnCode( int retCode
)
2319 m_retCode
= retCode
;
2322 int wxWindow::GetReturnCode()
2327 void wxWindow::Raise()
2329 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2331 if (m_widget
) gdk_window_raise( m_widget
->window
);
2334 void wxWindow::Lower()
2336 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2338 if (m_widget
) gdk_window_lower( m_widget
->window
);
2341 wxEvtHandler
*wxWindow::GetEventHandler() const
2343 return m_eventHandler
;
2346 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2348 m_eventHandler
= handler
;
2351 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2353 handler
->SetNextHandler(GetEventHandler());
2354 SetEventHandler(handler
);
2357 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2359 if (GetEventHandler())
2361 wxEvtHandler
*handlerA
= GetEventHandler();
2362 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2363 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2364 SetEventHandler(handlerB
);
2368 return (wxEvtHandler
*) NULL
;
2374 return (wxEvtHandler
*) NULL
;
2377 wxValidator
*wxWindow::GetValidator()
2379 return m_windowValidator
;
2382 void wxWindow::SetValidator( const wxValidator
& validator
)
2384 if (m_windowValidator
) delete m_windowValidator
;
2385 m_windowValidator
= validator
.Clone();
2386 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2389 void wxWindow::SetClientObject( wxClientData
*data
)
2391 if (m_clientObject
) delete m_clientObject
;
2392 m_clientObject
= data
;
2395 wxClientData
*wxWindow::GetClientObject()
2397 return m_clientObject
;
2400 void wxWindow::SetClientData( void *data
)
2402 m_clientData
= data
;
2405 void *wxWindow::GetClientData()
2407 return m_clientData
;
2410 bool wxWindow::IsBeingDeleted()
2415 void wxWindow::SetId( wxWindowID id
)
2420 wxWindowID
wxWindow::GetId() const
2425 void wxWindow::SetCursor( const wxCursor
&cursor
)
2427 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2431 if (cursor
== *m_cursor
) return;
2436 *m_cursor
= *wxSTANDARD_CURSOR
;
2439 if ((m_widget
) && (m_widget
->window
))
2440 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2442 if ((m_wxwindow
) && (m_wxwindow
->window
))
2443 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2446 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2451 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2453 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2455 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2459 gdk_window_clear_area( m_wxwindow
->window
,
2461 rect
->width
, rect
->height
);
2465 gdk_window_clear( m_wxwindow
->window
);
2472 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2474 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2478 GdkRectangle gdk_rect
;
2479 gdk_rect
.x
= rect
->x
;
2480 gdk_rect
.y
= rect
->y
;
2481 gdk_rect
.width
= rect
->width
;
2482 gdk_rect
.height
= rect
->height
;
2485 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2487 gtk_widget_draw( m_widget
, &gdk_rect
);
2491 wxRegion
wxWindow::GetUpdateRegion() const
2493 return m_updateRegion
;
2496 bool wxWindow::IsExposed( int x
, int y
) const
2498 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2501 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2503 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2506 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2508 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2511 bool wxWindow::IsExposed( const wxRect
& rect
) const
2513 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2516 void wxWindow::Clear()
2518 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2520 if (m_wxwindow
&& m_wxwindow
->window
)
2522 gdk_window_clear( m_wxwindow
->window
);
2527 void wxWindow::SetToolTip( const wxString
&tip
)
2531 m_toolTip
->SetTip( tip
);
2535 SetToolTip( new wxToolTip( tip
) );
2538 // setting empty tooltip text does not remove the tooltip any more for
2539 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2542 void wxWindow::SetToolTip( wxToolTip
*tip
)
2546 m_toolTip
->SetTip( (char*) NULL
);
2553 m_toolTip
->Apply( this );
2556 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2558 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2560 #endif // wxUSE_TOOLTIPS
2562 wxColour
wxWindow::GetBackgroundColour() const
2564 return m_backgroundColour
;
2567 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2569 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2571 if (m_backgroundColour
== colour
) return;
2573 m_backgroundColour
= colour
;
2574 if (!m_backgroundColour
.Ok()) return;
2576 if (m_wxwindow
&& m_wxwindow
->window
)
2578 /* wxMSW doesn't clear the window here. I don't do that
2579 either to provide compatibility. call Clear() to do
2582 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2583 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2586 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2588 if (sysbg
.Red() == colour
.Red() &&
2589 sysbg
.Green() == colour
.Green() &&
2590 sysbg
.Blue() == colour
.Blue())
2592 m_backgroundColour
= wxNullColour
;
2594 m_backgroundColour
= sysbg
;
2602 wxColour
wxWindow::GetForegroundColour() const
2604 return m_foregroundColour
;
2607 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2609 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2611 if (m_foregroundColour
== colour
) return;
2613 m_foregroundColour
= colour
;
2614 if (!m_foregroundColour
.Ok()) return;
2616 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2617 if (sysbg
.Red() == colour
.Red() &&
2618 sysbg
.Green() == colour
.Green() &&
2619 sysbg
.Blue() == colour
.Blue())
2621 m_backgroundColour
= wxNullColour
;
2623 m_backgroundColour
= sysbg
;
2631 GtkStyle
*wxWindow::GetWidgetStyle()
2633 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2637 gtk_widget_get_style( m_widget
) );
2639 return m_widgetStyle
;
2642 void wxWindow::SetWidgetStyle()
2644 GtkStyle
*style
= GetWidgetStyle();
2646 gdk_font_unref( style
->font
);
2647 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2649 if (m_foregroundColour
.Ok())
2651 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2652 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2653 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2654 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2657 if (m_backgroundColour
.Ok())
2659 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2660 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2661 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2662 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2663 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2664 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2665 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2666 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2667 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2671 void wxWindow::ApplyWidgetStyle()
2675 bool wxWindow::Validate()
2677 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2679 wxNode
*node
= m_children
.First();
2682 wxWindow
*child
= (wxWindow
*)node
->Data();
2683 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2687 node
= node
->Next();
2692 bool wxWindow::TransferDataToWindow()
2694 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2696 wxNode
*node
= m_children
.First();
2699 wxWindow
*child
= (wxWindow
*)node
->Data();
2700 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2701 !child
->GetValidator()->TransferToWindow() )
2703 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2706 node
= node
->Next();
2711 bool wxWindow::TransferDataFromWindow()
2713 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2715 wxNode
*node
= m_children
.First();
2718 wxWindow
*child
= (wxWindow
*)node
->Data();
2719 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2723 node
= node
->Next();
2728 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2730 m_acceleratorTable
= accel
;
2733 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2735 TransferDataToWindow();
2738 void wxWindow::InitDialog()
2740 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2742 wxInitDialogEvent
event(GetId());
2743 event
.SetEventObject( this );
2744 GetEventHandler()->ProcessEvent(event
);
2747 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2749 menu
->SetInvokingWindow( win
);
2750 wxNode
*node
= menu
->GetItems().First();
2753 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2754 if (menuitem
->IsSubMenu())
2756 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2758 node
= node
->Next();
2762 static gint gs_pop_x
= 0;
2763 static gint gs_pop_y
= 0;
2765 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2767 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2772 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2774 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2776 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2778 SetInvokingWindow( menu
, this );
2786 GTK_MENU(menu
->m_menu
),
2787 (GtkWidget
*) NULL
, // parent menu shell
2788 (GtkWidget
*) NULL
, // parent menu item
2789 (GtkMenuPositionFunc
) pop_pos_callback
,
2790 (gpointer
) this, // client data
2791 0, // button used to activate it
2792 0 //gs_timeLastClick // the time of activation
2797 #if wxUSE_DRAG_AND_DROP
2799 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2801 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2803 GtkWidget
*dnd_widget
= GetConnectWidget();
2805 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2807 if (m_dropTarget
) delete m_dropTarget
;
2808 m_dropTarget
= dropTarget
;
2810 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2813 wxDropTarget
*wxWindow::GetDropTarget() const
2815 return m_dropTarget
;
2820 GtkWidget
* wxWindow::GetConnectWidget()
2822 GtkWidget
*connect_widget
= m_widget
;
2823 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2825 return connect_widget
;
2828 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2830 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2831 return (window
== m_widget
->window
);
2834 void wxWindow::SetFont( const wxFont
&font
)
2836 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2838 if (m_font
== font
) return;
2840 if (((wxFont
*)&font
)->Ok())
2843 m_font
= *wxSWISS_FONT
;
2845 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2846 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2847 sysbg
.Green() == m_backgroundColour
.Green() &&
2848 sysbg
.Blue() == m_backgroundColour
.Blue())
2850 m_backgroundColour
= wxNullColour
;
2852 m_backgroundColour
= sysbg
;
2860 void wxWindow::SetWindowStyleFlag( long flag
)
2862 m_windowStyle
= flag
;
2865 long wxWindow::GetWindowStyleFlag() const
2867 return m_windowStyle
;
2870 void wxWindow::CaptureMouse()
2872 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2874 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2876 GtkWidget
*connect_widget
= GetConnectWidget();
2877 gtk_grab_add( connect_widget
);
2878 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2880 (GDK_BUTTON_PRESS_MASK
|
2881 GDK_BUTTON_RELEASE_MASK
|
2882 GDK_POINTER_MOTION_MASK
),
2889 void wxWindow::ReleaseMouse()
2891 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2893 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2895 GtkWidget
*connect_widget
= GetConnectWidget();
2896 gtk_grab_remove( connect_widget
);
2897 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2898 g_capturing
= FALSE
;
2901 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2905 wxString
wxWindow::GetTitle() const
2907 return (wxString
&)m_windowName
;
2910 wxString
wxWindow::GetLabel() const
2915 void wxWindow::SetName( const wxString
&name
)
2917 m_windowName
= name
;
2920 wxString
wxWindow::GetName() const
2922 return (wxString
&)m_windowName
;
2925 bool wxWindow::IsShown() const
2930 bool wxWindow::IsRetained()
2935 wxWindow
*wxWindow::FindWindow( long id
)
2937 if (id
== m_windowId
) return this;
2938 wxNode
*node
= m_children
.First();
2941 wxWindow
*child
= (wxWindow
*)node
->Data();
2942 wxWindow
*res
= child
->FindWindow( id
);
2943 if (res
) return res
;
2944 node
= node
->Next();
2946 return (wxWindow
*) NULL
;
2949 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2951 if (name
== m_windowName
) return this;
2952 wxNode
*node
= m_children
.First();
2955 wxWindow
*child
= (wxWindow
*)node
->Data();
2956 wxWindow
*res
= child
->FindWindow( name
);
2957 if (res
) return res
;
2958 node
= node
->Next();
2960 return (wxWindow
*) NULL
;
2963 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2964 int range
, bool refresh
)
2966 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2968 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2970 m_hasScrolling
= TRUE
;
2972 if (orient
== wxHORIZONTAL
)
2974 float fpos
= (float)pos
;
2975 float frange
= (float)range
;
2976 float fthumb
= (float)thumbVisible
;
2977 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2978 if (fpos
< 0.0) fpos
= 0.0;
2980 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2981 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2983 SetScrollPos( orient
, pos
, refresh
);
2987 m_oldHorizontalPos
= fpos
;
2989 m_hAdjust
->lower
= 0.0;
2990 m_hAdjust
->upper
= frange
;
2991 m_hAdjust
->value
= fpos
;
2992 m_hAdjust
->step_increment
= 1.0;
2993 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2994 m_hAdjust
->page_size
= fthumb
;
2998 float fpos
= (float)pos
;
2999 float frange
= (float)range
;
3000 float fthumb
= (float)thumbVisible
;
3001 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3002 if (fpos
< 0.0) fpos
= 0.0;
3004 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3005 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3007 SetScrollPos( orient
, pos
, refresh
);
3011 m_oldVerticalPos
= fpos
;
3013 m_vAdjust
->lower
= 0.0;
3014 m_vAdjust
->upper
= frange
;
3015 m_vAdjust
->value
= fpos
;
3016 m_vAdjust
->step_increment
= 1.0;
3017 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3018 m_vAdjust
->page_size
= fthumb
;
3021 if (m_wxwindow
->window
)
3023 if (orient
== wxHORIZONTAL
)
3024 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3026 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3028 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3032 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3034 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3036 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3038 if (orient
== wxHORIZONTAL
)
3040 float fpos
= (float)pos
;
3041 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3042 if (fpos
< 0.0) fpos
= 0.0;
3043 m_oldHorizontalPos
= fpos
;
3045 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3046 m_hAdjust
->value
= fpos
;
3050 float fpos
= (float)pos
;
3051 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3052 if (fpos
< 0.0) fpos
= 0.0;
3053 m_oldVerticalPos
= fpos
;
3055 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3056 m_vAdjust
->value
= fpos
;
3061 if (m_wxwindow
->window
)
3063 if (orient
== wxHORIZONTAL
)
3064 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3066 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3071 int wxWindow::GetScrollThumb( int orient
) const
3073 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3075 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3077 if (orient
== wxHORIZONTAL
)
3078 return (int)(m_hAdjust
->page_size
+0.5);
3080 return (int)(m_vAdjust
->page_size
+0.5);
3083 int wxWindow::GetScrollPos( int orient
) const
3085 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3087 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3089 if (orient
== wxHORIZONTAL
)
3090 return (int)(m_hAdjust
->value
+0.5);
3092 return (int)(m_vAdjust
->value
+0.5);
3095 int wxWindow::GetScrollRange( int orient
) const
3097 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3099 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3101 if (orient
== wxHORIZONTAL
)
3102 return (int)(m_hAdjust
->upper
+0.5);
3104 return (int)(m_vAdjust
->upper
+0.5);
3107 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3109 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3111 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3115 GetClientSize( &cw
, &ch
);
3117 int w
= cw
- abs(dx
);
3118 int h
= ch
- abs(dy
);
3119 if ((h
< 0) || (w
< 0))
3126 if (dx
< 0) s_x
= -dx
;
3127 if (dy
< 0) s_y
= -dy
;
3130 if (dx
> 0) d_x
= dx
;
3131 if (dy
> 0) d_y
= dy
;
3135 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3136 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3139 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3140 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3143 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3144 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3145 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3146 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3148 Refresh( TRUE
, &rect
);
3151 //-------------------------------------------------------------------------------------
3153 //-------------------------------------------------------------------------------------
3155 wxLayoutConstraints
*wxWindow::GetConstraints() const
3157 return m_constraints
;
3160 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3164 UnsetConstraints(m_constraints
);
3165 delete m_constraints
;
3167 m_constraints
= constraints
;
3170 // Make sure other windows know they're part of a 'meaningful relationship'
3171 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3172 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3173 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3174 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3175 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3176 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3177 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3178 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3179 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3180 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3181 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3182 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3183 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3184 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3185 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3186 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3192 void wxWindow::SetAutoLayout( bool autoLayout
)
3194 m_autoLayout
= autoLayout
;
3197 bool wxWindow::GetAutoLayout() const
3199 return m_autoLayout
;
3202 wxSizer
*wxWindow::GetSizer() const
3204 return m_windowSizer
;
3207 void wxWindow::SetSizerParent( wxWindow
*win
)
3209 m_sizerParent
= win
;
3212 wxWindow
*wxWindow::GetSizerParent() const
3214 return m_sizerParent
;
3217 // This removes any dangling pointers to this window
3218 // in other windows' constraintsInvolvedIn lists.
3219 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3223 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3224 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3225 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3226 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3227 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3228 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3229 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3230 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3231 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3232 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3233 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3234 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3235 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3236 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3237 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3238 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3242 // Back-pointer to other windows we're involved with, so if we delete
3243 // this window, we must delete any constraints we're involved with.
3244 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3246 if (!m_constraintsInvolvedIn
)
3247 m_constraintsInvolvedIn
= new wxList
;
3248 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3249 m_constraintsInvolvedIn
->Append(otherWin
);
3252 // REMOVE back-pointer to other windows we're involved with.
3253 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3255 if (m_constraintsInvolvedIn
)
3256 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3259 // Reset any constraints that mention this window
3260 void wxWindow::DeleteRelatedConstraints()
3262 if (m_constraintsInvolvedIn
)
3264 wxNode
*node
= m_constraintsInvolvedIn
->First();
3267 wxWindow
*win
= (wxWindow
*)node
->Data();
3268 wxNode
*next
= node
->Next();
3269 wxLayoutConstraints
*constr
= win
->GetConstraints();
3271 // Reset any constraints involving this window
3274 constr
->left
.ResetIfWin((wxWindow
*)this);
3275 constr
->top
.ResetIfWin((wxWindow
*)this);
3276 constr
->right
.ResetIfWin((wxWindow
*)this);
3277 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3278 constr
->width
.ResetIfWin((wxWindow
*)this);
3279 constr
->height
.ResetIfWin((wxWindow
*)this);
3280 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3281 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3286 delete m_constraintsInvolvedIn
;
3287 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3291 void wxWindow::SetSizer(wxSizer
*sizer
)
3293 m_windowSizer
= sizer
;
3295 sizer
->SetSizerParent((wxWindow
*)this);
3302 bool wxWindow::Layout()
3304 if (GetConstraints())
3307 GetClientSize(&w
, &h
);
3308 GetConstraints()->width
.SetValue(w
);
3309 GetConstraints()->height
.SetValue(h
);
3312 // If top level (one sizer), evaluate the sizer's constraints.
3316 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3317 GetSizer()->LayoutPhase1(&noChanges
);
3318 GetSizer()->LayoutPhase2(&noChanges
);
3319 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3324 // Otherwise, evaluate child constraints
3325 ResetConstraints(); // Mark all constraints as unevaluated
3326 DoPhase(1); // Just one phase need if no sizers involved
3328 SetConstraintSizes(); // Recursively set the real window sizes
3334 // Do a phase of evaluating constraints:
3335 // the default behaviour. wxSizers may do a similar
3336 // thing, but also impose their own 'constraints'
3337 // and order the evaluation differently.
3338 bool wxWindow::LayoutPhase1(int *noChanges
)
3340 wxLayoutConstraints
*constr
= GetConstraints();
3343 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3349 bool wxWindow::LayoutPhase2(int *noChanges
)
3359 // Do a phase of evaluating child constraints
3360 bool wxWindow::DoPhase(int phase
)
3362 int noIterations
= 0;
3363 int maxIterations
= 500;
3367 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3371 wxNode
*node
= m_children
.First();
3374 wxWindow
*child
= (wxWindow
*)node
->Data();
3375 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3377 wxLayoutConstraints
*constr
= child
->GetConstraints();
3380 if (succeeded
.Member(child
))
3385 int tempNoChanges
= 0;
3386 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3387 noChanges
+= tempNoChanges
;
3390 succeeded
.Append(child
);
3395 node
= node
->Next();
3402 void wxWindow::ResetConstraints()
3404 wxLayoutConstraints
*constr
= GetConstraints();
3407 constr
->left
.SetDone(FALSE
);
3408 constr
->top
.SetDone(FALSE
);
3409 constr
->right
.SetDone(FALSE
);
3410 constr
->bottom
.SetDone(FALSE
);
3411 constr
->width
.SetDone(FALSE
);
3412 constr
->height
.SetDone(FALSE
);
3413 constr
->centreX
.SetDone(FALSE
);
3414 constr
->centreY
.SetDone(FALSE
);
3416 wxNode
*node
= m_children
.First();
3419 wxWindow
*win
= (wxWindow
*)node
->Data();
3420 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3421 win
->ResetConstraints();
3422 node
= node
->Next();
3426 // Need to distinguish between setting the 'fake' size for
3427 // windows and sizers, and setting the real values.
3428 void wxWindow::SetConstraintSizes(bool recurse
)
3430 wxLayoutConstraints
*constr
= GetConstraints();
3431 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3432 constr
->width
.GetDone() && constr
->height
.GetDone())
3434 int x
= constr
->left
.GetValue();
3435 int y
= constr
->top
.GetValue();
3436 int w
= constr
->width
.GetValue();
3437 int h
= constr
->height
.GetValue();
3439 // If we don't want to resize this window, just move it...
3440 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3441 (constr
->height
.GetRelationship() != wxAsIs
))
3443 // Calls Layout() recursively. AAAGH. How can we stop that.
3444 // Simply take Layout() out of non-top level OnSizes.
3445 SizerSetSize(x
, y
, w
, h
);
3454 char *windowClass
= this->GetClassInfo()->GetClassName();
3457 if (GetName() == "")
3458 winName
= "unnamed";
3460 winName
= GetName();
3461 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3462 (const char *)windowClass
,
3463 (const char *)winName
);
3464 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3465 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3466 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3467 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3468 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3473 wxNode
*node
= m_children
.First();
3476 wxWindow
*win
= (wxWindow
*)node
->Data();
3477 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3478 win
->SetConstraintSizes();
3479 node
= node
->Next();
3484 // This assumes that all sizers are 'on' the same
3485 // window, i.e. the parent of this window.
3486 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3488 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3489 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3493 m_sizerParent
->GetPosition(&xp
, &yp
);
3494 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3499 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3503 TransformSizerToActual(&xx
, &yy
);
3504 SetSize(xx
, yy
, w
, h
);
3507 void wxWindow::SizerMove(int x
, int y
)
3511 TransformSizerToActual(&xx
, &yy
);
3515 // Only set the size/position of the constraint (if any)
3516 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3518 wxLayoutConstraints
*constr
= GetConstraints();
3523 constr
->left
.SetValue(x
);
3524 constr
->left
.SetDone(TRUE
);
3528 constr
->top
.SetValue(y
);
3529 constr
->top
.SetDone(TRUE
);
3533 constr
->width
.SetValue(w
);
3534 constr
->width
.SetDone(TRUE
);
3538 constr
->height
.SetValue(h
);
3539 constr
->height
.SetDone(TRUE
);
3544 void wxWindow::MoveConstraint(int x
, int y
)
3546 wxLayoutConstraints
*constr
= GetConstraints();
3551 constr
->left
.SetValue(x
);
3552 constr
->left
.SetDone(TRUE
);
3556 constr
->top
.SetValue(y
);
3557 constr
->top
.SetDone(TRUE
);
3562 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3564 wxLayoutConstraints
*constr
= GetConstraints();
3567 *w
= constr
->width
.GetValue();
3568 *h
= constr
->height
.GetValue();
3574 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3576 wxLayoutConstraints
*constr
= GetConstraints();
3579 *w
= constr
->width
.GetValue();
3580 *h
= constr
->height
.GetValue();
3583 GetClientSize(w
, h
);
3586 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3588 wxLayoutConstraints
*constr
= GetConstraints();
3591 *x
= constr
->left
.GetValue();
3592 *y
= constr
->top
.GetValue();