1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "window.h"
16 #include "wx/window.h"
20 #include "wx/layout.h"
22 #include "wx/dialog.h"
23 #include "wx/msgdlg.h"
25 #if wxUSE_DRAG_AND_DROP
30 #include "wx/tooltip.h"
34 #include "wx/statusbr.h"
36 #include "wx/settings.h"
43 #include "gdk/gdkprivate.h"
44 #include "gdk/gdkkeysyms.h"
45 #include "wx/gtk/win_gtk.h"
47 //-----------------------------------------------------------------------------
48 // documentation on internals
49 //-----------------------------------------------------------------------------
52 I have been asked several times about writing some documentation about
53 the GTK port of wxWindows, especially its internal structures. Obviously,
54 you cannot understand wxGTK without knowing a little about the GTK, but
55 some more information about what the wxWindow, which is the base class
56 for all other window classes, does seems required as well.
58 What does wxWindow do? It contains the common interface for the following
59 jobs of its descendants:
61 1) Define the rudimentary behaviour common to all window classes, such as
62 resizing, intercepting user input (so as to make it possible to use these
63 events for special purposes in a derived class), window names etc.
65 2) Provide the possibility to contain and manage children, if the derived
66 class is allowed to contain children, which holds true for those window
67 classes which do not display a native GTK widget. To name them, these
68 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
69 work classes are a special case and are handled a bit differently from
70 the rest. The same holds true for the wxNotebook class.
72 3) Provide the possibility to draw into a client area of a window. This,
73 too, only holds true for classes that do not display a native GTK widget
76 4) Provide the entire mechanism for scrolling widgets. This actual inter-
77 face for this is usually in wxScrolledWindow, but the GTK implementation
80 5) A multitude of helper or extra methods for special purposes, such as
81 Drag'n'Drop, managing validators etc.
83 Normally one might expect, that one wxWindows window would always correspond
84 to one GTK widget. Under GTK, there is no such allround widget that has all
85 the functionality. Moreover, the GTK defines a client area as a different
86 widget from the actual widget you are handling. Last but not least some
87 special classes (e.g. wxFrame) handle different categories of widgets and
88 still have the possibility to draw something in the client area.
89 It was therefore required to write a special purpose GTK widget, that would
90 represent a client area in the sense of wxWindows capable to do the jobs
91 2), 3) and 4). I have written this class and it resides in win_gtk.c of
94 All windows must have a widget, with which they interact with other under-
95 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
96 thw wxWindow class has a member variable called m_widget which holds a
97 pointer to this widget. When the window class represents a GTK native widget,
98 this is (in most cases) the only GTK widget the class manages. E.g. the
99 wxStatitText class handles only a GtkLabel widget a pointer to which you
100 can find in m_widget (defined in wxWindow)
102 When the class has a client area for drawing into and for containing children
103 it has to handle the client area widget (of the type GtkMyFixed, defined in
104 win_gtk.c), but there could be any number of widgets, handled by a class
105 The common rule for all windows is only, that the widget that interacts with
106 the rest of GTK must be referenced in m_widget and all other widgets must be
107 children of this widget on the GTK level. The top-most widget, which also
108 represents the client area, must be in the m_wxwindow field and must be of
111 As I said, the window classes that display a GTK native widget only have
112 one widget, so in the case of e.g. the wxButton class m_widget holds a
113 pointer to a GtkButton widget. But windows with client areas (for drawing
114 and children) have a m_widget field that is a pointer to a GtkScrolled-
115 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
116 one is (in the GTK sense) a child of the GtkScrolledWindow.
118 If the m_wxwindow field is set, then all input to this widget is inter-
119 cepted and sent to the wxWindows class. If not, all input to the widget
120 that gets pointed to by m_widget gets intercepted and sent to the class.
124 //-------------------------------------------------------------------------
125 // conditional compilation
126 //-------------------------------------------------------------------------
128 #if (GTK_MINOR_VERSION == 1)
129 #if (GTK_MICRO_VERSION >= 5)
130 #define NEW_GTK_SCROLL_CODE
134 //-----------------------------------------------------------------------------
136 //-----------------------------------------------------------------------------
140 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
141 GdkEvent
*WXUNUSED(event
),
144 printf( "FOCUS NOW AT: " );
151 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
159 char *s
= new char[tmp
.Length()+1];
161 strcpy( s
, WXSTRINGCAST tmp
);
163 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
164 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
169 //-----------------------------------------------------------------------------
171 //-----------------------------------------------------------------------------
173 extern wxList wxPendingDelete
;
174 extern wxList wxTopLevelWindows
;
175 extern bool g_blockEventsOnDrag
;
176 extern bool g_blockEventsOnScroll
;
177 static bool g_capturing
= FALSE
;
178 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
180 // hack: we need something to pass to gtk_menu_popup, so we store the time of
181 // the last click here
182 static guint32 gs_timeLastClick
= 0;
184 //-----------------------------------------------------------------------------
185 // "expose_event" (of m_wxwindow, not of m_widget)
186 //-----------------------------------------------------------------------------
188 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
190 if (!win
->HasVMT()) return;
192 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
194 gdk_event
->area
.width
,
195 gdk_event
->area
.height
);
197 if (gdk_event
->count
> 0) return;
200 printf( "OnExpose from " );
201 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
202 printf( win->GetClassInfo()->GetClassName() );
206 wxPaintEvent
event( win
->GetId() );
207 event
.SetEventObject( win
);
208 win
->GetEventHandler()->ProcessEvent( event
);
210 win
->m_updateRegion
.Clear();
213 //-----------------------------------------------------------------------------
214 // "draw" (of m_wxwindow, not of m_widget)
215 //-----------------------------------------------------------------------------
217 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
219 if (!win
->HasVMT()) return;
221 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
223 wxPaintEvent
event( win
->GetId() );
224 event
.SetEventObject( win
);
225 win
->GetEventHandler()->ProcessEvent( event
);
227 win
->m_updateRegion
.Clear();
230 //-----------------------------------------------------------------------------
231 // "key_press_event" from any window
232 //-----------------------------------------------------------------------------
234 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
236 if (!win
->HasVMT()) return FALSE
;
237 if (g_blockEventsOnDrag
) return FALSE
;
240 printf( "OnKeyPress from " );
241 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
242 printf( win->GetClassInfo()->GetClassName() );
247 switch (gdk_event
->keyval
)
249 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
250 case GDK_ISO_Left_Tab
:
252 case GDK_Tab
: key_code
= WXK_TAB
; break;
253 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
254 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
255 case GDK_Return
: key_code
= WXK_RETURN
; break;
256 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
257 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
258 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
259 case GDK_Delete
: key_code
= WXK_DELETE
; break;
260 case GDK_Home
: key_code
= WXK_HOME
; break;
261 case GDK_Left
: key_code
= WXK_LEFT
; break;
262 case GDK_Up
: key_code
= WXK_UP
; break;
263 case GDK_Right
: key_code
= WXK_RIGHT
; break;
264 case GDK_Down
: key_code
= WXK_DOWN
; break;
265 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
266 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
267 case GDK_Next
: key_code
= WXK_NEXT
; break;
268 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
269 case GDK_End
: key_code
= WXK_END
; break;
270 case GDK_Begin
: key_code
= WXK_HOME
; break;
271 case GDK_Select
: key_code
= WXK_SELECT
; break;
272 case GDK_Print
: key_code
= WXK_PRINT
; break;
273 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
274 case GDK_Insert
: key_code
= WXK_INSERT
; break;
275 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
276 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
277 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
278 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
279 case GDK_KP_Up
: key_code
= WXK_UP
; break;
280 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
281 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
282 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
283 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
284 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
285 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
286 case GDK_KP_End
: key_code
= WXK_END
; break;
287 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
288 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
289 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
290 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
291 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
292 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
293 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
294 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
295 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
296 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
297 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
298 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
299 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
300 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
301 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
302 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
303 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
304 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
305 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
306 case GDK_F1
: key_code
= WXK_F1
; break;
307 case GDK_F2
: key_code
= WXK_F2
; break;
308 case GDK_F3
: key_code
= WXK_F3
; break;
309 case GDK_F4
: key_code
= WXK_F4
; break;
310 case GDK_F5
: key_code
= WXK_F5
; break;
311 case GDK_F6
: key_code
= WXK_F6
; break;
312 case GDK_F7
: key_code
= WXK_F7
; break;
313 case GDK_F8
: key_code
= WXK_F8
; break;
314 case GDK_F9
: key_code
= WXK_F9
; break;
315 case GDK_F10
: key_code
= WXK_F10
; break;
316 case GDK_F11
: key_code
= WXK_F11
; break;
317 case GDK_F12
: key_code
= WXK_F12
; break;
320 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
321 key_code
= gdk_event
->keyval
;
325 if (!key_code
) return FALSE
;
327 wxKeyEvent
event( wxEVT_KEY_DOWN
);
328 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
329 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
330 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
331 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
332 event
.m_keyCode
= key_code
;
335 event
.SetEventObject( win
);
337 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
341 wxWindow
*ancestor
= win
;
344 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
347 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
348 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
351 ancestor
= ancestor
->GetParent();
355 // win is a control: tab can be propagated up
357 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
358 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
360 wxNavigationKeyEvent new_event
;
361 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
362 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
363 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
364 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
365 new_event
.SetCurrentFocus( win
);
366 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
370 (gdk_event
->keyval
== GDK_Escape
) )
372 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
373 new_event
.SetEventObject( win
);
374 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
378 Damn, I forgot why this didn't work, but it didn't work.
380 // win is a panel: up can be propagated to the panel
381 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
382 (gdk_event->keyval == GDK_Up))
384 win->m_parent->SetFocus();
388 // win is a panel: left/right can be propagated to the panel
389 if ((!ret) && (win->m_wxwindow) &&
390 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
391 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
393 wxNavigationKeyEvent new_event;
394 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
395 new_event.SetCurrentFocus( win );
396 ret = win->GetEventHandler()->ProcessEvent( new_event );
402 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
408 //-----------------------------------------------------------------------------
409 // "key_release_event" from any window
410 //-----------------------------------------------------------------------------
412 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
414 if (!win
->HasVMT()) return FALSE
;
415 if (g_blockEventsOnDrag
) return FALSE
;
418 printf( "OnKeyRelease from " );
419 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
420 printf( win->GetClassInfo()->GetClassName() );
425 switch (gdk_event
->keyval
)
427 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
428 case GDK_ISO_Left_Tab
:
430 case GDK_Tab
: key_code
= WXK_TAB
; break;
431 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
432 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
433 case GDK_Return
: key_code
= WXK_RETURN
; break;
434 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
435 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
436 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
437 case GDK_Delete
: key_code
= WXK_DELETE
; break;
438 case GDK_Home
: key_code
= WXK_HOME
; break;
439 case GDK_Left
: key_code
= WXK_LEFT
; break;
440 case GDK_Up
: key_code
= WXK_UP
; break;
441 case GDK_Right
: key_code
= WXK_RIGHT
; break;
442 case GDK_Down
: key_code
= WXK_DOWN
; break;
443 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
444 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
445 case GDK_Next
: key_code
= WXK_NEXT
; break;
446 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
447 case GDK_End
: key_code
= WXK_END
; break;
448 case GDK_Begin
: key_code
= WXK_HOME
; break;
449 case GDK_Select
: key_code
= WXK_SELECT
; break;
450 case GDK_Print
: key_code
= WXK_PRINT
; break;
451 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
452 case GDK_Insert
: key_code
= WXK_INSERT
; break;
453 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
454 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
455 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
456 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
457 case GDK_KP_Up
: key_code
= WXK_UP
; break;
458 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
459 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
460 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
461 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
462 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
463 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
464 case GDK_KP_End
: key_code
= WXK_END
; break;
465 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
466 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
467 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
468 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
469 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
470 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
471 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
472 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
473 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
474 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
475 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
476 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
477 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
478 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
479 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
480 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
481 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
482 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
483 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
484 case GDK_F1
: key_code
= WXK_F1
; break;
485 case GDK_F2
: key_code
= WXK_F2
; break;
486 case GDK_F3
: key_code
= WXK_F3
; break;
487 case GDK_F4
: key_code
= WXK_F4
; break;
488 case GDK_F5
: key_code
= WXK_F5
; break;
489 case GDK_F6
: key_code
= WXK_F6
; break;
490 case GDK_F7
: key_code
= WXK_F7
; break;
491 case GDK_F8
: key_code
= WXK_F8
; break;
492 case GDK_F9
: key_code
= WXK_F9
; break;
493 case GDK_F10
: key_code
= WXK_F10
; break;
494 case GDK_F11
: key_code
= WXK_F11
; break;
495 case GDK_F12
: key_code
= WXK_F12
; break;
498 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
499 key_code
= gdk_event
->keyval
;
503 if (!key_code
) return FALSE
;
505 wxKeyEvent
event( wxEVT_KEY_UP
);
506 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
507 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
508 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
509 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
510 event
.m_keyCode
= key_code
;
513 event
.SetEventObject( win
);
515 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
519 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
525 //-----------------------------------------------------------------------------
526 // "button_press_event"
527 //-----------------------------------------------------------------------------
529 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
531 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
533 if (g_blockEventsOnDrag
) return TRUE
;
534 if (g_blockEventsOnScroll
) return TRUE
;
538 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
540 gtk_widget_grab_focus (win
->m_wxwindow
);
543 printf( "GrabFocus from " );
544 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
545 printf( win->GetClassInfo()->GetClassName() );
552 if (!win
->HasVMT()) return TRUE
;
555 printf( "OnButtonPress from " );
556 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
557 printf( win->GetClassInfo()->GetClassName() );
561 wxEventType event_type
= wxEVT_LEFT_DOWN
;
563 if (gdk_event
->button
== 1)
565 switch (gdk_event
->type
)
567 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
568 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
572 else if (gdk_event
->button
== 2)
574 switch (gdk_event
->type
)
576 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
577 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
581 else if (gdk_event
->button
== 3)
583 switch (gdk_event
->type
)
585 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
586 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
591 wxMouseEvent
event( event_type
);
592 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
593 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
594 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
595 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
596 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
597 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
598 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
600 event
.m_x
= (long)gdk_event
->x
;
601 event
.m_y
= (long)gdk_event
->y
;
603 // Some control don't have their own X window and thus cannot get
608 wxNode
*node
= win
->GetChildren().First();
611 wxWindow
*child
= (wxWindow
*)node
->Data();
613 if (child
->m_isStaticBox
)
615 // wxStaticBox is transparent in the box itself
618 int xx1
= child
->m_x
;
619 int yy1
= child
->m_y
;
620 int xx2
= child
->m_x
+ child
->m_width
;
621 int yy2
= child
->m_x
+ child
->m_height
;
624 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
626 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
628 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
630 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
633 event
.m_x
-= child
->m_x
;
634 event
.m_y
-= child
->m_y
;
641 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
642 (child
->m_x
<= event
.m_x
) &&
643 (child
->m_y
<= event
.m_y
) &&
644 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
645 (child
->m_y
+child
->m_height
>= event
.m_y
))
648 event
.m_x
-= child
->m_x
;
649 event
.m_y
-= child
->m_y
;
657 wxPoint
pt(win
->GetClientAreaOrigin());
661 event
.SetEventObject( win
);
663 gs_timeLastClick
= gdk_event
->time
;
665 if (win
->GetEventHandler()->ProcessEvent( event
))
666 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
671 //-----------------------------------------------------------------------------
672 // "button_release_event"
673 //-----------------------------------------------------------------------------
675 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
677 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
679 if (g_blockEventsOnDrag
) return TRUE
;
680 if (g_blockEventsOnScroll
) return TRUE
;
682 if (!win
->HasVMT()) return TRUE
;
685 printf( "OnButtonRelease from " );
686 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
687 printf( win->GetClassInfo()->GetClassName() );
691 wxEventType event_type
= wxEVT_NULL
;
693 switch (gdk_event
->button
)
695 case 1: event_type
= wxEVT_LEFT_UP
; break;
696 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
697 case 3: event_type
= wxEVT_RIGHT_UP
; break;
700 wxMouseEvent
event( event_type
);
701 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
702 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
703 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
704 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
705 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
706 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
707 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
708 event
.m_x
= (long)gdk_event
->x
;
709 event
.m_y
= (long)gdk_event
->y
;
711 // Some control don't have their own X window and thus cannot get
716 wxNode
*node
= win
->GetChildren().First();
719 wxWindow
*child
= (wxWindow
*)node
->Data();
721 if (child
->m_isStaticBox
)
723 // wxStaticBox is transparent in the box itself
726 int xx1
= child
->m_x
;
727 int yy1
= child
->m_y
;
728 int xx2
= child
->m_x
+ child
->m_width
;
729 int yy2
= child
->m_x
+ child
->m_height
;
732 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
734 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
736 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
738 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
741 event
.m_x
-= child
->m_x
;
742 event
.m_y
-= child
->m_y
;
749 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
750 (child
->m_x
<= event
.m_x
) &&
751 (child
->m_y
<= event
.m_y
) &&
752 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
753 (child
->m_y
+child
->m_height
>= event
.m_y
))
756 event
.m_x
-= child
->m_x
;
757 event
.m_y
-= child
->m_y
;
765 wxPoint
pt(win
->GetClientAreaOrigin());
769 event
.SetEventObject( win
);
771 if (win
->GetEventHandler()->ProcessEvent( event
))
772 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
777 //-----------------------------------------------------------------------------
778 // "motion_notify_event"
779 //-----------------------------------------------------------------------------
781 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
783 if (gdk_event
->is_hint
)
787 GdkModifierType state
;
788 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
791 gdk_event
->state
= state
;
794 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
796 if (g_blockEventsOnDrag
) return TRUE
;
797 if (g_blockEventsOnScroll
) return TRUE
;
799 if (!win
->HasVMT()) return TRUE
;
802 printf( "OnMotion from " );
803 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
804 printf( win->GetClassInfo()->GetClassName() );
808 wxMouseEvent
event( wxEVT_MOTION
);
809 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
810 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
811 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
812 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
813 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
814 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
815 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
817 event
.m_x
= (long)gdk_event
->x
;
818 event
.m_y
= (long)gdk_event
->y
;
820 // Some control don't have their own X window and thus cannot get
825 wxNode
*node
= win
->GetChildren().First();
828 wxWindow
*child
= (wxWindow
*)node
->Data();
830 if (child
->m_isStaticBox
)
832 // wxStaticBox is transparent in the box itself
835 int xx1
= child
->m_x
;
836 int yy1
= child
->m_y
;
837 int xx2
= child
->m_x
+ child
->m_width
;
838 int yy2
= child
->m_x
+ child
->m_height
;
841 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
843 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
845 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
847 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
850 event
.m_x
-= child
->m_x
;
851 event
.m_y
-= child
->m_y
;
858 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
859 (child
->m_x
<= event
.m_x
) &&
860 (child
->m_y
<= event
.m_y
) &&
861 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
862 (child
->m_y
+child
->m_height
>= event
.m_y
))
865 event
.m_x
-= child
->m_x
;
866 event
.m_y
-= child
->m_y
;
874 wxPoint
pt(win
->GetClientAreaOrigin());
878 event
.SetEventObject( win
);
880 if (win
->GetEventHandler()->ProcessEvent( event
))
881 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
886 //-----------------------------------------------------------------------------
888 //-----------------------------------------------------------------------------
890 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
892 if (g_blockEventsOnDrag
) return TRUE
;
898 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
900 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
902 printf( "SetFocus flag from " );
903 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
904 printf( win->GetClassInfo()->GetClassName() );
910 if (!win
->HasVMT()) return TRUE
;
913 printf( "OnSetFocus from " );
914 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
915 printf( win->GetClassInfo()->GetClassName() );
917 printf( WXSTRINGCAST win->GetLabel() );
921 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
922 event
.SetEventObject( win
);
924 if (win
->GetEventHandler()->ProcessEvent( event
))
925 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
930 //-----------------------------------------------------------------------------
932 //-----------------------------------------------------------------------------
934 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
936 if (g_blockEventsOnDrag
) return TRUE
;
939 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
940 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
943 if (!win
->HasVMT()) return TRUE
;
946 printf( "OnKillFocus from " );
947 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
948 printf( win->GetClassInfo()->GetClassName() );
952 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
953 event
.SetEventObject( win
);
955 if (win
->GetEventHandler()->ProcessEvent( event
))
956 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
961 //-----------------------------------------------------------------------------
962 // "enter_notify_event"
963 //-----------------------------------------------------------------------------
965 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
967 if (g_blockEventsOnDrag
) return TRUE
;
969 if ((widget
->window
) && (win
->m_cursor
))
970 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
972 if (widget
->window
!= gdk_event
->window
) return TRUE
;
974 if (!win
->HasVMT()) return TRUE
;
977 printf( "OnEnter from " );
978 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
979 printf( win->GetClassInfo()->GetClassName() );
983 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
984 event
.SetEventObject( win
);
988 GdkModifierType state
= (GdkModifierType
)0;
990 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
992 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
993 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
994 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
995 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
996 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
997 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
998 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1000 event
.m_x
= (long)x
;
1001 event
.m_y
= (long)y
;
1003 wxPoint
pt(win
->GetClientAreaOrigin());
1007 if (win
->GetEventHandler()->ProcessEvent( event
))
1008 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1013 //-----------------------------------------------------------------------------
1014 // "leave_notify_event"
1015 //-----------------------------------------------------------------------------
1017 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1019 if (g_blockEventsOnDrag
) return TRUE
;
1021 if ((widget
->window
) && (win
->m_cursor
))
1022 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1024 if (widget
->window
!= gdk_event
->window
) return TRUE
;
1026 if (!win
->HasVMT()) return TRUE
;
1029 printf( "OnLeave from " );
1030 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1031 printf( win->GetClassInfo()->GetClassName() );
1035 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1036 event
.SetEventObject( win
);
1040 GdkModifierType state
= (GdkModifierType
)0;
1042 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1044 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1045 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1046 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1047 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1048 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1049 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1050 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1052 event
.m_x
= (long)x
;
1053 event
.m_y
= (long)y
;
1055 wxPoint
pt(win
->GetClientAreaOrigin());
1059 if (win
->GetEventHandler()->ProcessEvent( event
))
1060 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1065 //-----------------------------------------------------------------------------
1066 // "value_changed" from m_vAdjust
1067 //-----------------------------------------------------------------------------
1069 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1071 if (g_blockEventsOnDrag
) return;
1074 printf( "OnVScroll from " );
1075 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1076 printf( win->GetClassInfo()->GetClassName() );
1080 if (!win
->HasVMT()) return;
1082 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1083 if (fabs(diff
) < 0.2) return;
1085 wxEventType command
= wxEVT_NULL
;
1087 float line_step
= win
->m_vAdjust
->step_increment
;
1088 float page_step
= win
->m_vAdjust
->page_increment
;
1090 if (win
->m_isScrolling
)
1092 command
= wxEVT_SCROLL_THUMBTRACK
;
1096 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1097 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1098 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1099 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1100 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1101 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1102 else command
= wxEVT_SCROLL_THUMBTRACK
;
1105 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1107 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1108 event
.SetEventObject( win
);
1109 win
->GetEventHandler()->ProcessEvent( event
);
1112 //-----------------------------------------------------------------------------
1113 // "value_changed" from m_hAdjust
1114 //-----------------------------------------------------------------------------
1116 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1118 if (g_blockEventsOnDrag
) return;
1121 printf( "OnHScroll from " );
1122 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1123 printf( win->GetClassInfo()->GetClassName() );
1127 if (!win
->HasVMT()) return;
1129 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1130 if (fabs(diff
) < 0.2) return;
1132 wxEventType command
= wxEVT_NULL
;
1134 float line_step
= win
->m_hAdjust
->step_increment
;
1135 float page_step
= win
->m_hAdjust
->page_increment
;
1137 if (win
->m_isScrolling
)
1139 command
= wxEVT_SCROLL_THUMBTRACK
;
1143 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1144 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1145 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1146 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1147 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1148 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1149 else command
= wxEVT_SCROLL_THUMBTRACK
;
1152 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1154 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1155 event
.SetEventObject( win
);
1156 win
->GetEventHandler()->ProcessEvent( event
);
1159 //-----------------------------------------------------------------------------
1160 // "changed" from m_vAdjust
1161 //-----------------------------------------------------------------------------
1163 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1165 if (g_blockEventsOnDrag
) return;
1168 printf( "OnVScroll change from " );
1169 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1170 printf( win->GetClassInfo()->GetClassName() );
1174 if (!win
->HasVMT()) return;
1176 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1177 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1179 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1180 event
.SetEventObject( win
);
1181 win
->GetEventHandler()->ProcessEvent( event
);
1184 //-----------------------------------------------------------------------------
1185 // "changed" from m_hAdjust
1186 //-----------------------------------------------------------------------------
1188 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1190 if (g_blockEventsOnDrag
) return;
1193 printf( "OnHScroll change from " );
1194 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1195 printf( win->GetClassInfo()->GetClassName() );
1199 if (!win
->HasVMT()) return;
1201 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1202 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1204 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1205 event
.SetEventObject( win
);
1206 win
->GetEventHandler()->ProcessEvent( event
);
1209 //-----------------------------------------------------------------------------
1210 // "button_press_event" from scrollbar
1211 //-----------------------------------------------------------------------------
1213 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1214 GdkEventButton
*WXUNUSED(gdk_event
),
1217 // don't test here as we can release the mouse while being over
1218 // a different window then the slider
1220 // if (gdk_event->window != widget->slider) return FALSE;
1222 win
->m_isScrolling
= TRUE
;
1223 g_blockEventsOnScroll
= TRUE
;
1228 //-----------------------------------------------------------------------------
1229 // "button_release_event" from scrollbar
1230 //-----------------------------------------------------------------------------
1232 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1233 GdkEventButton
*WXUNUSED(gdk_event
),
1237 // don't test here as we can release the mouse while being over
1238 // a different window then the slider
1240 // if (gdk_event->window != widget->slider) return FALSE;
1242 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1244 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1245 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1247 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1249 win
->m_isScrolling
= FALSE
;
1250 g_blockEventsOnScroll
= FALSE
;
1255 //-----------------------------------------------------------------------------
1256 // InsertChild for wxWindow.
1257 //-----------------------------------------------------------------------------
1259 /* Callback for wxWindow. This very strange beast has to be used because
1260 * C++ has no virtual methods in a constructor. We have to emulate a
1261 * virtual function here as wxNotebook requires a different way to insert
1262 * a child in it. I had opted for creating a wxNotebookPage window class
1263 * which would have made this superfluous (such in the MDI window system),
1264 * but no-one was listening to me... */
1266 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1268 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1269 GTK_WIDGET(child
->m_widget
),
1273 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1277 if (wxIS_KIND_OF(parent
,wxFrame
))
1279 parent
->m_sizeSet
= FALSE
;
1282 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1284 /* we now allow a window to get the focus as long as it
1285 doesn't have any children. */
1286 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1290 //-----------------------------------------------------------------------------
1292 //-----------------------------------------------------------------------------
1294 wxWindow
* wxGetActiveWindow()
1296 return g_focusWindow
;
1299 //-----------------------------------------------------------------------------
1301 //-----------------------------------------------------------------------------
1303 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1305 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1306 EVT_SIZE(wxWindow::OnSize
)
1307 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1308 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1309 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1312 void wxWindow::Init()
1316 m_widget
= (GtkWidget
*) NULL
;
1317 m_wxwindow
= (GtkWidget
*) NULL
;
1318 m_parent
= (wxWindow
*) NULL
;
1319 m_children
.DeleteContents( FALSE
);
1332 m_eventHandler
= this;
1333 m_windowValidator
= (wxValidator
*) NULL
;
1337 m_cursor
= (wxCursor
*) NULL
;
1338 m_font
= *wxSWISS_FONT
;
1340 m_windowName
= "noname";
1342 m_constraints
= (wxLayoutConstraints
*) NULL
;
1343 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1344 m_windowSizer
= (wxSizer
*) NULL
;
1345 m_sizerParent
= (wxWindow
*) NULL
;
1346 m_autoLayout
= FALSE
;
1350 m_needParent
= TRUE
;
1352 m_hasScrolling
= FALSE
;
1353 m_isScrolling
= FALSE
;
1354 m_hAdjust
= (GtkAdjustment
*) NULL
;
1355 m_vAdjust
= (GtkAdjustment
*) NULL
;
1356 m_oldHorizontalPos
= 0.0;
1357 m_oldVerticalPos
= 0.0;
1362 #if wxUSE_DRAG_AND_DROP
1363 m_dropTarget
= (wxDropTarget
*) NULL
;
1366 m_scrollGC
= (GdkGC
*) NULL
;
1367 m_widgetStyle
= (GtkStyle
*) NULL
;
1369 m_insertCallback
= wxInsertChildInWindow
;
1371 m_clientObject
= (wxClientData
*) NULL
;
1372 m_clientData
= NULL
;
1374 m_isStaticBox
= FALSE
;
1375 m_acceptsFocus
= FALSE
;
1378 m_toolTip
= (wxToolTip
*) NULL
;
1379 #endif // wxUSE_TOOLTIPS
1382 wxWindow::wxWindow()
1387 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1388 const wxPoint
&pos
, const wxSize
&size
,
1389 long style
, const wxString
&name
)
1393 Create( parent
, id
, pos
, size
, style
, name
);
1396 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1397 const wxPoint
&pos
, const wxSize
&size
,
1398 long style
, const wxString
&name
)
1400 wxASSERT_MSG( m_isWindow
, "Init() must have been called before!" );
1402 PreCreation( parent
, id
, pos
, size
, style
, name
);
1404 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1405 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1408 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1411 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1414 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1415 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1418 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1419 scroll_class
->scrollbar_spacing
= 0;
1421 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1423 m_oldHorizontalPos
= 0.0;
1424 m_oldVerticalPos
= 0.0;
1426 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1427 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1429 m_wxwindow
= gtk_myfixed_new();
1432 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1435 #ifdef NEW_GTK_SCROLL_CODE
1436 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1437 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1439 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1440 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1444 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1447 if (m_windowStyle
& wxRAISED_BORDER
)
1449 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1451 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1453 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1457 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1460 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1462 /* we now allow a window to get the focus as long as it
1463 doesn't have any children. */
1464 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1465 m_acceptsFocus
= FALSE
;
1469 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1470 m_acceptsFocus
= TRUE
;
1473 // shut the viewport up
1474 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1475 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1477 // I _really_ don't want scrollbars in the beginning
1478 m_vAdjust
->lower
= 0.0;
1479 m_vAdjust
->upper
= 1.0;
1480 m_vAdjust
->value
= 0.0;
1481 m_vAdjust
->step_increment
= 1.0;
1482 m_vAdjust
->page_increment
= 1.0;
1483 m_vAdjust
->page_size
= 5.0;
1484 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1485 m_hAdjust
->lower
= 0.0;
1486 m_hAdjust
->upper
= 1.0;
1487 m_hAdjust
->value
= 0.0;
1488 m_hAdjust
->step_increment
= 1.0;
1489 m_hAdjust
->page_increment
= 1.0;
1490 m_hAdjust
->page_size
= 5.0;
1491 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1493 // these handlers block mouse events to any window during scrolling
1494 // such as motion events and prevent GTK and wxWindows from fighting
1495 // over where the slider should be
1497 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1498 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1500 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1501 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1503 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1504 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1506 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1507 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1509 // these handers het notified when screen updates are required either when
1510 // scrolling or when the window size (and therefore scrollbar configuration)
1513 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1514 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1515 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1516 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1518 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1519 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1520 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1521 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1523 gtk_widget_show( m_wxwindow
);
1525 if (m_parent
) m_parent
->AddChild( this );
1527 (m_parent
->m_insertCallback
)( m_parent
, this );
1536 wxWindow::~wxWindow()
1540 #if wxUSE_DRAG_AND_DROP
1543 delete m_dropTarget
;
1544 m_dropTarget
= (wxDropTarget
*) NULL
;
1552 m_toolTip
= (wxToolTip
*) NULL
;
1554 #endif // wxUSE_TOOLTIPS
1556 if (m_widget
) Show( FALSE
);
1560 if (m_parent
) m_parent
->RemoveChild( this );
1562 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1564 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1566 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1568 if (m_widget
) gtk_widget_destroy( m_widget
);
1570 if (m_cursor
) delete m_cursor
;
1572 DeleteRelatedConstraints();
1575 /* This removes any dangling pointers to this window
1576 * in other windows' constraintsInvolvedIn lists. */
1577 UnsetConstraints(m_constraints
);
1578 delete m_constraints
;
1579 m_constraints
= (wxLayoutConstraints
*) NULL
;
1584 delete m_windowSizer
;
1585 m_windowSizer
= (wxSizer
*) NULL
;
1587 /* If this is a child of a sizer, remove self from parent */
1588 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1590 /* Just in case the window has been Closed, but
1591 * we're then deleting immediately: don't leave
1592 * dangling pointers. */
1593 wxPendingDelete
.DeleteObject(this);
1595 /* Just in case we've loaded a top-level window via
1596 * wxWindow::LoadNativeDialog but we weren't a dialog
1598 wxTopLevelWindows
.DeleteObject(this);
1600 if (m_windowValidator
) delete m_windowValidator
;
1602 if (m_clientObject
) delete m_clientObject
;
1605 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1606 const wxPoint
&pos
, const wxSize
&size
,
1607 long style
, const wxString
&name
)
1609 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1611 m_widget
= (GtkWidget
*) NULL
;
1612 m_wxwindow
= (GtkWidget
*) NULL
;
1615 m_children
.DeleteContents( FALSE
);
1618 if (m_width
== -1) m_width
= 20;
1620 if (m_height
== -1) m_height
= 20;
1625 if (!m_needParent
) /* some reasonable defaults */
1629 m_x
= (gdk_screen_width () - m_width
) / 2;
1630 if (m_x
< 10) m_x
= 10;
1634 m_y
= (gdk_screen_height () - m_height
) / 2;
1635 if (m_y
< 10) m_y
= 10;
1646 m_eventHandler
= this;
1648 m_windowId
= id
== -1 ? wxNewId() : id
;
1652 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1653 m_font
= *wxSWISS_FONT
;
1654 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1655 m_foregroundColour
= *wxBLACK
;
1656 m_windowStyle
= style
;
1657 m_windowName
= name
;
1659 m_constraints
= (wxLayoutConstraints
*) NULL
;
1660 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1661 m_windowSizer
= (wxSizer
*) NULL
;
1662 m_sizerParent
= (wxWindow
*) NULL
;
1663 m_autoLayout
= FALSE
;
1665 m_hasScrolling
= FALSE
;
1666 m_isScrolling
= FALSE
;
1667 m_hAdjust
= (GtkAdjustment
*) NULL
;
1668 m_vAdjust
= (GtkAdjustment
*) NULL
;
1669 m_oldHorizontalPos
= 0.0;
1670 m_oldVerticalPos
= 0.0;
1675 #if wxUSE_DRAG_AND_DROP
1676 m_dropTarget
= (wxDropTarget
*) NULL
;
1679 m_windowValidator
= (wxValidator
*) NULL
;
1680 m_scrollGC
= (GdkGC
*) NULL
;
1681 m_widgetStyle
= (GtkStyle
*) NULL
;
1683 m_clientObject
= (wxClientData
*)NULL
;
1684 m_clientData
= NULL
;
1686 m_isStaticBox
= FALSE
;
1689 m_toolTip
= (wxToolTip
*) NULL
;
1690 #endif // wxUSE_TOOLTIPS
1693 void wxWindow::PostCreation()
1695 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1699 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1700 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1702 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1703 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1706 ConnectWidget( GetConnectWidget() );
1708 /* we force the creation of wxFrame and wxDialog in the respective code */
1709 if (m_parent
) gtk_widget_realize( m_widget
);
1711 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1713 SetCursor( *wxSTANDARD_CURSOR
);
1718 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1720 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1721 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1723 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1724 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1726 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1727 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1729 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1730 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1732 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1733 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1735 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1736 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1738 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1739 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1741 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1742 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1744 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1745 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1748 bool wxWindow::HasVMT()
1753 bool wxWindow::Close( bool force
)
1755 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1757 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1758 event
.SetEventObject(this);
1759 event
.SetCanVeto(!force
);
1761 /* return FALSE if window wasn't closed because the application vetoed the
1763 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1766 bool wxWindow::Destroy()
1768 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1775 bool wxWindow::DestroyChildren()
1778 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1781 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1784 if (m_children
.Member(child
)) delete node
;
1790 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1792 // are we to set fonts here ?
1795 wxPoint
wxWindow::GetClientAreaOrigin() const
1797 return wxPoint(0,0);
1800 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1802 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1804 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1810 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1812 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1813 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1815 if (m_resizing
) return; /* I don't like recursions */
1818 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1820 /* don't set the size for children of wxNotebook, just take the values. */
1828 int old_width
= m_width
;
1829 int old_height
= m_height
;
1831 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1833 if (x
!= -1) m_x
= x
;
1834 if (y
!= -1) m_y
= y
;
1835 if (width
!= -1) m_width
= width
;
1836 if (height
!= -1) m_height
= height
;
1846 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1848 if (width
== -1) m_width
= 80;
1851 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1853 if (height
== -1) m_height
= 26;
1856 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1857 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1858 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1859 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1861 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1863 /* the default button has a border around it */
1866 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1867 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border
);
1869 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1873 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1874 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1876 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1877 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1883 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1884 event
.SetEventObject( this );
1885 GetEventHandler()->ProcessEvent( event
);
1890 void wxWindow::OnInternalIdle()
1895 void wxWindow::GetSize( int *width
, int *height
) const
1897 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1899 if (width
) (*width
) = m_width
;
1900 if (height
) (*height
) = m_height
;
1903 void wxWindow::DoSetClientSize( int width
, int height
)
1905 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1909 SetSize( width
, height
);
1916 if (!m_hasScrolling
)
1918 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1920 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1921 (m_windowStyle
& wxSUNKEN_BORDER
))
1923 dw
+= 2 * window_class
->xthickness
;
1924 dh
+= 2 * window_class
->ythickness
;
1929 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1930 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1932 #ifdef NEW_GTK_SCROLL_CODE
1933 GtkWidget
*viewport
= scroll_window
->child
;
1935 GtkWidget
*viewport
= scroll_window
->viewport
;
1938 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1940 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1941 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1943 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1944 (m_windowStyle
& wxSUNKEN_BORDER
))
1946 dw
+= 2 * viewport_class
->xthickness
;
1947 dh
+= 2 * viewport_class
->ythickness
;
1950 if (scroll_window
->vscrollbar_visible
)
1952 dw
+= vscrollbar
->allocation
.width
;
1953 dw
+= scroll_class
->scrollbar_spacing
;
1956 if (scroll_window
->hscrollbar_visible
)
1958 dh
+= hscrollbar
->allocation
.height
;
1959 dw
+= scroll_class
->scrollbar_spacing
;
1963 SetSize( width
+dw
, height
+dh
);
1967 void wxWindow::GetClientSize( int *width
, int *height
) const
1969 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1973 if (width
) (*width
) = m_width
;
1974 if (height
) (*height
) = m_height
;
1981 if (!m_hasScrolling
)
1983 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1985 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1986 (m_windowStyle
& wxSUNKEN_BORDER
))
1988 dw
+= 2 * window_class
->xthickness
;
1989 dh
+= 2 * window_class
->ythickness
;
1994 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1995 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1997 #ifdef NEW_GTK_SCROLL_CODE
1998 GtkWidget
*viewport
= scroll_window
->child
;
2000 GtkWidget
*viewport
= scroll_window
->viewport
;
2003 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2005 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2006 (m_windowStyle
& wxSUNKEN_BORDER
))
2008 dw
+= 2 * viewport_class
->xthickness
;
2009 dh
+= 2 * viewport_class
->ythickness
;
2012 if (scroll_window
->vscrollbar_visible
)
2014 // dw += vscrollbar->allocation.width;
2015 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
2016 dw
+= scroll_class
->scrollbar_spacing
;
2019 if (scroll_window
->hscrollbar_visible
)
2021 // dh += hscrollbar->allocation.height;
2023 dh
+= scroll_class
->scrollbar_spacing
;
2027 if (width
) (*width
) = m_width
- dw
;
2028 if (height
) (*height
) = m_height
- dh
;
2032 void wxWindow::GetPosition( int *x
, int *y
) const
2034 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2040 void wxWindow::ClientToScreen( int *x
, int *y
)
2042 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2044 GdkWindow
*source
= (GdkWindow
*) NULL
;
2046 source
= m_wxwindow
->window
;
2048 source
= m_widget
->window
;
2052 gdk_window_get_origin( source
, &org_x
, &org_y
);
2056 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2058 org_x
+= m_widget
->allocation
.x
;
2059 org_y
+= m_widget
->allocation
.y
;
2063 wxPoint
pt(GetClientAreaOrigin());
2071 void wxWindow::ScreenToClient( int *x
, int *y
)
2073 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2075 GdkWindow
*source
= (GdkWindow
*) NULL
;
2077 source
= m_wxwindow
->window
;
2079 source
= m_widget
->window
;
2083 gdk_window_get_origin( source
, &org_x
, &org_y
);
2087 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2089 org_x
+= m_widget
->allocation
.x
;
2090 org_y
+= m_widget
->allocation
.y
;
2094 wxPoint
pt(GetClientAreaOrigin());
2102 void wxWindow::Centre( int direction
)
2104 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2113 m_parent
->GetSize( &p_w
, &p_h
);
2114 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2115 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2119 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2120 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2126 void wxWindow::Fit()
2128 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2132 wxNode
*node
= m_children
.First();
2135 wxWindow
*win
= (wxWindow
*)node
->Data();
2137 win
->GetPosition(&wx
, &wy
);
2138 win
->GetSize(&ww
, &wh
);
2139 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2140 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2142 node
= node
->Next();
2145 SetClientSize(maxX
+ 7, maxY
+ 14);
2148 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2150 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2158 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2160 // if (GetAutoLayout()) Layout();
2163 bool wxWindow::Show( bool show
)
2165 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2167 if (show
== m_isShown
) return TRUE
;
2170 gtk_widget_show( m_widget
);
2172 gtk_widget_hide( m_widget
);
2179 void wxWindow::Enable( bool enable
)
2181 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2183 m_isEnabled
= enable
;
2185 gtk_widget_set_sensitive( m_widget
, enable
);
2186 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2189 int wxWindow::GetCharHeight() const
2191 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2193 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2195 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2197 return font
->ascent
+ font
->descent
;
2200 int wxWindow::GetCharWidth() const
2202 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2204 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2206 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2208 return gdk_string_width( font
, "H" );
2211 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2212 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2214 wxFont fontToUse
= m_font
;
2215 if (theFont
) fontToUse
= *theFont
;
2217 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2219 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2220 if (x
) (*x
) = gdk_string_width( font
, string
);
2221 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2222 if (descent
) (*descent
) = font
->descent
;
2223 if (externalLeading
) (*externalLeading
) = 0; // ??
2226 void wxWindow::MakeModal( bool modal
)
2230 // Disable all other windows
2231 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2233 wxNode
*node
= wxTopLevelWindows
.First();
2236 wxWindow
*win
= (wxWindow
*)node
->Data();
2237 if (win
!= this) win
->Enable(!modal
);
2239 node
= node
->Next();
2244 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2246 event
.SetEventType( wxEVT_CHAR
);
2248 if (!GetEventHandler()->ProcessEvent( event
))
2254 void wxWindow::SetFocus()
2256 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2258 GtkWidget
*connect_widget
= GetConnectWidget();
2261 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2263 gtk_widget_grab_focus (connect_widget
);
2265 else if (GTK_IS_CONTAINER(connect_widget
))
2267 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2275 wxWindow
*wxWindow::FindFocus()
2277 return g_focusWindow
;
2280 bool wxWindow::AcceptsFocus() const
2282 return IsEnabled() && IsShown() && m_acceptsFocus
;
2285 void wxWindow::AddChild( wxWindow
*child
)
2287 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2288 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2290 m_children
.Append( child
);
2293 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2295 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2297 wxWindow
*oldParent
= GetParent();
2299 if (oldParent
) oldParent
->RemoveChild( this );
2301 gtk_widget_unparent( m_widget
);
2305 newParent
->AddChild( this );
2306 (newParent
->m_insertCallback
)( newParent
, this );
2312 void wxWindow::RemoveChild( wxWindow
*child
)
2314 m_children
.DeleteObject( child
);
2315 child
->m_parent
= (wxWindow
*) NULL
;
2318 void wxWindow::SetReturnCode( int retCode
)
2320 m_retCode
= retCode
;
2323 int wxWindow::GetReturnCode()
2328 void wxWindow::Raise()
2330 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2332 if (m_widget
) gdk_window_raise( m_widget
->window
);
2335 void wxWindow::Lower()
2337 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2339 if (m_widget
) gdk_window_lower( m_widget
->window
);
2342 wxEvtHandler
*wxWindow::GetEventHandler() const
2344 return m_eventHandler
;
2347 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2349 m_eventHandler
= handler
;
2352 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2354 handler
->SetNextHandler(GetEventHandler());
2355 SetEventHandler(handler
);
2358 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2360 if (GetEventHandler())
2362 wxEvtHandler
*handlerA
= GetEventHandler();
2363 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2364 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2365 SetEventHandler(handlerB
);
2369 return (wxEvtHandler
*) NULL
;
2375 return (wxEvtHandler
*) NULL
;
2378 wxValidator
*wxWindow::GetValidator()
2380 return m_windowValidator
;
2383 void wxWindow::SetValidator( const wxValidator
& validator
)
2385 if (m_windowValidator
) delete m_windowValidator
;
2386 m_windowValidator
= validator
.Clone();
2387 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2390 void wxWindow::SetClientObject( wxClientData
*data
)
2392 if (m_clientObject
) delete m_clientObject
;
2393 m_clientObject
= data
;
2396 wxClientData
*wxWindow::GetClientObject()
2398 return m_clientObject
;
2401 void wxWindow::SetClientData( void *data
)
2403 m_clientData
= data
;
2406 void *wxWindow::GetClientData()
2408 return m_clientData
;
2411 bool wxWindow::IsBeingDeleted()
2416 void wxWindow::SetId( wxWindowID id
)
2421 wxWindowID
wxWindow::GetId() const
2426 void wxWindow::SetCursor( const wxCursor
&cursor
)
2428 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2432 if (cursor
== *m_cursor
) return;
2437 *m_cursor
= *wxSTANDARD_CURSOR
;
2440 if ((m_widget
) && (m_widget
->window
))
2441 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2443 if ((m_wxwindow
) && (m_wxwindow
->window
))
2444 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2447 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2452 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2454 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2456 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2460 gdk_window_clear_area( m_wxwindow
->window
,
2462 rect
->width
, rect
->height
);
2466 gdk_window_clear( m_wxwindow
->window
);
2473 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2475 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2479 GdkRectangle gdk_rect
;
2480 gdk_rect
.x
= rect
->x
;
2481 gdk_rect
.y
= rect
->y
;
2482 gdk_rect
.width
= rect
->width
;
2483 gdk_rect
.height
= rect
->height
;
2486 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2488 gtk_widget_draw( m_widget
, &gdk_rect
);
2492 wxRegion
wxWindow::GetUpdateRegion() const
2494 return m_updateRegion
;
2497 bool wxWindow::IsExposed( int x
, int y
) const
2499 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2502 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2504 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2507 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2509 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2512 bool wxWindow::IsExposed( const wxRect
& rect
) const
2514 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2517 void wxWindow::Clear()
2519 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2521 if (m_wxwindow
&& m_wxwindow
->window
)
2523 gdk_window_clear( m_wxwindow
->window
);
2528 void wxWindow::SetToolTip( const wxString
&tip
)
2532 m_toolTip
->SetTip( tip
);
2536 SetToolTip( new wxToolTip( tip
) );
2539 // setting empty tooltip text does not remove the tooltip any more for
2540 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2543 void wxWindow::SetToolTip( wxToolTip
*tip
)
2547 m_toolTip
->SetTip( (char*) NULL
);
2554 m_toolTip
->Apply( this );
2557 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2559 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2561 #endif // wxUSE_TOOLTIPS
2563 wxColour
wxWindow::GetBackgroundColour() const
2565 return m_backgroundColour
;
2568 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2570 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2572 if (m_backgroundColour
== colour
) return;
2574 m_backgroundColour
= colour
;
2575 if (!m_backgroundColour
.Ok()) return;
2577 if (m_wxwindow
&& m_wxwindow
->window
)
2579 /* wxMSW doesn't clear the window here. I don't do that
2580 either to provide compatibility. call Clear() to do
2583 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2584 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2587 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2589 if (sysbg
.Red() == colour
.Red() &&
2590 sysbg
.Green() == colour
.Green() &&
2591 sysbg
.Blue() == colour
.Blue())
2593 m_backgroundColour
= wxNullColour
;
2595 m_backgroundColour
= sysbg
;
2603 wxColour
wxWindow::GetForegroundColour() const
2605 return m_foregroundColour
;
2608 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2610 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2612 if (m_foregroundColour
== colour
) return;
2614 m_foregroundColour
= colour
;
2615 if (!m_foregroundColour
.Ok()) return;
2617 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2618 if (sysbg
.Red() == colour
.Red() &&
2619 sysbg
.Green() == colour
.Green() &&
2620 sysbg
.Blue() == colour
.Blue())
2622 m_backgroundColour
= wxNullColour
;
2624 m_backgroundColour
= sysbg
;
2632 GtkStyle
*wxWindow::GetWidgetStyle()
2634 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2638 gtk_widget_get_style( m_widget
) );
2640 return m_widgetStyle
;
2643 void wxWindow::SetWidgetStyle()
2645 GtkStyle
*style
= GetWidgetStyle();
2647 gdk_font_unref( style
->font
);
2648 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2650 if (m_foregroundColour
.Ok())
2652 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2653 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2654 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2655 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2658 if (m_backgroundColour
.Ok())
2660 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2661 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2662 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2663 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2664 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2665 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2666 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2667 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2668 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2672 void wxWindow::ApplyWidgetStyle()
2676 bool wxWindow::Validate()
2678 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2680 wxNode
*node
= m_children
.First();
2683 wxWindow
*child
= (wxWindow
*)node
->Data();
2684 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2688 node
= node
->Next();
2693 bool wxWindow::TransferDataToWindow()
2695 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2697 wxNode
*node
= m_children
.First();
2700 wxWindow
*child
= (wxWindow
*)node
->Data();
2701 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2702 !child
->GetValidator()->TransferToWindow() )
2704 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2707 node
= node
->Next();
2712 bool wxWindow::TransferDataFromWindow()
2714 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2716 wxNode
*node
= m_children
.First();
2719 wxWindow
*child
= (wxWindow
*)node
->Data();
2720 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2724 node
= node
->Next();
2729 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2731 m_acceleratorTable
= accel
;
2734 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2736 TransferDataToWindow();
2739 void wxWindow::InitDialog()
2741 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2743 wxInitDialogEvent
event(GetId());
2744 event
.SetEventObject( this );
2745 GetEventHandler()->ProcessEvent(event
);
2748 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2750 menu
->SetInvokingWindow( win
);
2751 wxNode
*node
= menu
->m_items
.First();
2754 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2755 if (menuitem
->IsSubMenu())
2757 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2759 node
= node
->Next();
2763 static gint gs_pop_x
= 0;
2764 static gint gs_pop_y
= 0;
2766 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2768 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2773 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2775 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2777 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2779 SetInvokingWindow( menu
, this );
2787 GTK_MENU(menu
->m_menu
),
2788 (GtkWidget
*) NULL
, // parent menu shell
2789 (GtkWidget
*) NULL
, // parent menu item
2790 (GtkMenuPositionFunc
) pop_pos_callback
,
2791 (gpointer
) this, // client data
2792 0, // button used to activate it
2793 0 //gs_timeLastClick // the time of activation
2798 #if wxUSE_DRAG_AND_DROP
2800 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2802 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2804 GtkWidget
*dnd_widget
= GetConnectWidget();
2806 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2808 if (m_dropTarget
) delete m_dropTarget
;
2809 m_dropTarget
= dropTarget
;
2811 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2814 wxDropTarget
*wxWindow::GetDropTarget() const
2816 return m_dropTarget
;
2821 GtkWidget
* wxWindow::GetConnectWidget()
2823 GtkWidget
*connect_widget
= m_widget
;
2824 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2826 return connect_widget
;
2829 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2831 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2832 return (window
== m_widget
->window
);
2835 void wxWindow::SetFont( const wxFont
&font
)
2837 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2839 if (((wxFont
*)&font
)->Ok())
2842 m_font
= *wxSWISS_FONT
;
2844 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2845 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2846 sysbg
.Green() == m_backgroundColour
.Green() &&
2847 sysbg
.Blue() == m_backgroundColour
.Blue())
2849 m_backgroundColour
= wxNullColour
;
2851 m_backgroundColour
= sysbg
;
2859 void wxWindow::SetWindowStyleFlag( long flag
)
2861 m_windowStyle
= flag
;
2864 long wxWindow::GetWindowStyleFlag() const
2866 return m_windowStyle
;
2869 void wxWindow::CaptureMouse()
2871 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2873 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2875 GtkWidget
*connect_widget
= GetConnectWidget();
2876 gtk_grab_add( connect_widget
);
2877 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2879 (GDK_BUTTON_PRESS_MASK
|
2880 GDK_BUTTON_RELEASE_MASK
|
2881 GDK_POINTER_MOTION_MASK
),
2888 void wxWindow::ReleaseMouse()
2890 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2892 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2894 GtkWidget
*connect_widget
= GetConnectWidget();
2895 gtk_grab_remove( connect_widget
);
2896 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2897 g_capturing
= FALSE
;
2900 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2904 wxString
wxWindow::GetTitle() const
2906 return (wxString
&)m_windowName
;
2909 wxString
wxWindow::GetLabel() const
2914 void wxWindow::SetName( const wxString
&name
)
2916 m_windowName
= name
;
2919 wxString
wxWindow::GetName() const
2921 return (wxString
&)m_windowName
;
2924 bool wxWindow::IsShown() const
2929 bool wxWindow::IsRetained()
2934 wxWindow
*wxWindow::FindWindow( long id
)
2936 if (id
== m_windowId
) return this;
2937 wxNode
*node
= m_children
.First();
2940 wxWindow
*child
= (wxWindow
*)node
->Data();
2941 wxWindow
*res
= child
->FindWindow( id
);
2942 if (res
) return res
;
2943 node
= node
->Next();
2945 return (wxWindow
*) NULL
;
2948 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2950 if (name
== m_windowName
) return this;
2951 wxNode
*node
= m_children
.First();
2954 wxWindow
*child
= (wxWindow
*)node
->Data();
2955 wxWindow
*res
= child
->FindWindow( name
);
2956 if (res
) return res
;
2957 node
= node
->Next();
2959 return (wxWindow
*) NULL
;
2962 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2963 int range
, bool refresh
)
2965 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2967 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2969 m_hasScrolling
= TRUE
;
2971 if (orient
== wxHORIZONTAL
)
2973 float fpos
= (float)pos
;
2974 float frange
= (float)range
;
2975 float fthumb
= (float)thumbVisible
;
2976 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2977 if (fpos
< 0.0) fpos
= 0.0;
2979 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2980 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2982 SetScrollPos( orient
, pos
, refresh
);
2986 m_oldHorizontalPos
= fpos
;
2988 m_hAdjust
->lower
= 0.0;
2989 m_hAdjust
->upper
= frange
;
2990 m_hAdjust
->value
= fpos
;
2991 m_hAdjust
->step_increment
= 1.0;
2992 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2993 m_hAdjust
->page_size
= fthumb
;
2997 float fpos
= (float)pos
;
2998 float frange
= (float)range
;
2999 float fthumb
= (float)thumbVisible
;
3000 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3001 if (fpos
< 0.0) fpos
= 0.0;
3003 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3004 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3006 SetScrollPos( orient
, pos
, refresh
);
3010 m_oldVerticalPos
= fpos
;
3012 m_vAdjust
->lower
= 0.0;
3013 m_vAdjust
->upper
= frange
;
3014 m_vAdjust
->value
= fpos
;
3015 m_vAdjust
->step_increment
= 1.0;
3016 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3017 m_vAdjust
->page_size
= fthumb
;
3020 if (m_wxwindow
->window
)
3022 if (orient
== wxHORIZONTAL
)
3023 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3025 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3027 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3031 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3033 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3035 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3037 if (orient
== wxHORIZONTAL
)
3039 float fpos
= (float)pos
;
3040 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3041 if (fpos
< 0.0) fpos
= 0.0;
3042 m_oldHorizontalPos
= fpos
;
3044 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3045 m_hAdjust
->value
= fpos
;
3049 float fpos
= (float)pos
;
3050 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3051 if (fpos
< 0.0) fpos
= 0.0;
3052 m_oldVerticalPos
= fpos
;
3054 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3055 m_vAdjust
->value
= fpos
;
3060 if (m_wxwindow
->window
)
3062 if (orient
== wxHORIZONTAL
)
3063 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3065 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3070 int wxWindow::GetScrollThumb( int orient
) const
3072 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3074 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3076 if (orient
== wxHORIZONTAL
)
3077 return (int)(m_hAdjust
->page_size
+0.5);
3079 return (int)(m_vAdjust
->page_size
+0.5);
3082 int wxWindow::GetScrollPos( int orient
) const
3084 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3086 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3088 if (orient
== wxHORIZONTAL
)
3089 return (int)(m_hAdjust
->value
+0.5);
3091 return (int)(m_vAdjust
->value
+0.5);
3094 int wxWindow::GetScrollRange( int orient
) const
3096 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3098 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3100 if (orient
== wxHORIZONTAL
)
3101 return (int)(m_hAdjust
->upper
+0.5);
3103 return (int)(m_vAdjust
->upper
+0.5);
3106 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3108 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3110 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3114 GetClientSize( &cw
, &ch
);
3116 int w
= cw
- abs(dx
);
3117 int h
= ch
- abs(dy
);
3118 if ((h
< 0) || (w
< 0))
3125 if (dx
< 0) s_x
= -dx
;
3126 if (dy
< 0) s_y
= -dy
;
3129 if (dx
> 0) d_x
= dx
;
3130 if (dy
> 0) d_y
= dy
;
3134 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3135 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3138 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3139 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3142 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3143 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3144 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3145 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3147 Refresh( TRUE
, &rect
);
3150 //-------------------------------------------------------------------------------------
3152 //-------------------------------------------------------------------------------------
3154 wxLayoutConstraints
*wxWindow::GetConstraints() const
3156 return m_constraints
;
3159 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3163 UnsetConstraints(m_constraints
);
3164 delete m_constraints
;
3166 m_constraints
= constraints
;
3169 // Make sure other windows know they're part of a 'meaningful relationship'
3170 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3171 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3172 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3173 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3174 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3175 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3176 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3177 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3178 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3179 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3180 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3181 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3182 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3183 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3184 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3185 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3191 void wxWindow::SetAutoLayout( bool autoLayout
)
3193 m_autoLayout
= autoLayout
;
3196 bool wxWindow::GetAutoLayout() const
3198 return m_autoLayout
;
3201 wxSizer
*wxWindow::GetSizer() const
3203 return m_windowSizer
;
3206 void wxWindow::SetSizerParent( wxWindow
*win
)
3208 m_sizerParent
= win
;
3211 wxWindow
*wxWindow::GetSizerParent() const
3213 return m_sizerParent
;
3216 // This removes any dangling pointers to this window
3217 // in other windows' constraintsInvolvedIn lists.
3218 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3222 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3223 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3224 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3225 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3226 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3227 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3228 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3229 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3230 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3231 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3232 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3233 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3234 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3235 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3236 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3237 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3241 // Back-pointer to other windows we're involved with, so if we delete
3242 // this window, we must delete any constraints we're involved with.
3243 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3245 if (!m_constraintsInvolvedIn
)
3246 m_constraintsInvolvedIn
= new wxList
;
3247 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3248 m_constraintsInvolvedIn
->Append(otherWin
);
3251 // REMOVE back-pointer to other windows we're involved with.
3252 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3254 if (m_constraintsInvolvedIn
)
3255 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3258 // Reset any constraints that mention this window
3259 void wxWindow::DeleteRelatedConstraints()
3261 if (m_constraintsInvolvedIn
)
3263 wxNode
*node
= m_constraintsInvolvedIn
->First();
3266 wxWindow
*win
= (wxWindow
*)node
->Data();
3267 wxNode
*next
= node
->Next();
3268 wxLayoutConstraints
*constr
= win
->GetConstraints();
3270 // Reset any constraints involving this window
3273 constr
->left
.ResetIfWin((wxWindow
*)this);
3274 constr
->top
.ResetIfWin((wxWindow
*)this);
3275 constr
->right
.ResetIfWin((wxWindow
*)this);
3276 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3277 constr
->width
.ResetIfWin((wxWindow
*)this);
3278 constr
->height
.ResetIfWin((wxWindow
*)this);
3279 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3280 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3285 delete m_constraintsInvolvedIn
;
3286 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3290 void wxWindow::SetSizer(wxSizer
*sizer
)
3292 m_windowSizer
= sizer
;
3294 sizer
->SetSizerParent((wxWindow
*)this);
3301 bool wxWindow::Layout()
3303 if (GetConstraints())
3306 GetClientSize(&w
, &h
);
3307 GetConstraints()->width
.SetValue(w
);
3308 GetConstraints()->height
.SetValue(h
);
3311 // If top level (one sizer), evaluate the sizer's constraints.
3315 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3316 GetSizer()->LayoutPhase1(&noChanges
);
3317 GetSizer()->LayoutPhase2(&noChanges
);
3318 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3323 // Otherwise, evaluate child constraints
3324 ResetConstraints(); // Mark all constraints as unevaluated
3325 DoPhase(1); // Just one phase need if no sizers involved
3327 SetConstraintSizes(); // Recursively set the real window sizes
3333 // Do a phase of evaluating constraints:
3334 // the default behaviour. wxSizers may do a similar
3335 // thing, but also impose their own 'constraints'
3336 // and order the evaluation differently.
3337 bool wxWindow::LayoutPhase1(int *noChanges
)
3339 wxLayoutConstraints
*constr
= GetConstraints();
3342 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3348 bool wxWindow::LayoutPhase2(int *noChanges
)
3358 // Do a phase of evaluating child constraints
3359 bool wxWindow::DoPhase(int phase
)
3361 int noIterations
= 0;
3362 int maxIterations
= 500;
3366 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3370 wxNode
*node
= m_children
.First();
3373 wxWindow
*child
= (wxWindow
*)node
->Data();
3374 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3376 wxLayoutConstraints
*constr
= child
->GetConstraints();
3379 if (succeeded
.Member(child
))
3384 int tempNoChanges
= 0;
3385 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3386 noChanges
+= tempNoChanges
;
3389 succeeded
.Append(child
);
3394 node
= node
->Next();
3401 void wxWindow::ResetConstraints()
3403 wxLayoutConstraints
*constr
= GetConstraints();
3406 constr
->left
.SetDone(FALSE
);
3407 constr
->top
.SetDone(FALSE
);
3408 constr
->right
.SetDone(FALSE
);
3409 constr
->bottom
.SetDone(FALSE
);
3410 constr
->width
.SetDone(FALSE
);
3411 constr
->height
.SetDone(FALSE
);
3412 constr
->centreX
.SetDone(FALSE
);
3413 constr
->centreY
.SetDone(FALSE
);
3415 wxNode
*node
= m_children
.First();
3418 wxWindow
*win
= (wxWindow
*)node
->Data();
3419 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3420 win
->ResetConstraints();
3421 node
= node
->Next();
3425 // Need to distinguish between setting the 'fake' size for
3426 // windows and sizers, and setting the real values.
3427 void wxWindow::SetConstraintSizes(bool recurse
)
3429 wxLayoutConstraints
*constr
= GetConstraints();
3430 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3431 constr
->width
.GetDone() && constr
->height
.GetDone())
3433 int x
= constr
->left
.GetValue();
3434 int y
= constr
->top
.GetValue();
3435 int w
= constr
->width
.GetValue();
3436 int h
= constr
->height
.GetValue();
3438 // If we don't want to resize this window, just move it...
3439 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3440 (constr
->height
.GetRelationship() != wxAsIs
))
3442 // Calls Layout() recursively. AAAGH. How can we stop that.
3443 // Simply take Layout() out of non-top level OnSizes.
3444 SizerSetSize(x
, y
, w
, h
);
3453 char *windowClass
= this->GetClassInfo()->GetClassName();
3456 if (GetName() == "")
3457 winName
= "unnamed";
3459 winName
= GetName();
3460 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3461 (const char *)windowClass
,
3462 (const char *)winName
);
3463 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3464 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3465 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3466 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3467 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3472 wxNode
*node
= m_children
.First();
3475 wxWindow
*win
= (wxWindow
*)node
->Data();
3476 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3477 win
->SetConstraintSizes();
3478 node
= node
->Next();
3483 // This assumes that all sizers are 'on' the same
3484 // window, i.e. the parent of this window.
3485 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3487 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3488 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3492 m_sizerParent
->GetPosition(&xp
, &yp
);
3493 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3498 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3502 TransformSizerToActual(&xx
, &yy
);
3503 SetSize(xx
, yy
, w
, h
);
3506 void wxWindow::SizerMove(int x
, int y
)
3510 TransformSizerToActual(&xx
, &yy
);
3514 // Only set the size/position of the constraint (if any)
3515 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3517 wxLayoutConstraints
*constr
= GetConstraints();
3522 constr
->left
.SetValue(x
);
3523 constr
->left
.SetDone(TRUE
);
3527 constr
->top
.SetValue(y
);
3528 constr
->top
.SetDone(TRUE
);
3532 constr
->width
.SetValue(w
);
3533 constr
->width
.SetDone(TRUE
);
3537 constr
->height
.SetValue(h
);
3538 constr
->height
.SetDone(TRUE
);
3543 void wxWindow::MoveConstraint(int x
, int y
)
3545 wxLayoutConstraints
*constr
= GetConstraints();
3550 constr
->left
.SetValue(x
);
3551 constr
->left
.SetDone(TRUE
);
3555 constr
->top
.SetValue(y
);
3556 constr
->top
.SetDone(TRUE
);
3561 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3563 wxLayoutConstraints
*constr
= GetConstraints();
3566 *w
= constr
->width
.GetValue();
3567 *h
= constr
->height
.GetValue();
3573 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3575 wxLayoutConstraints
*constr
= GetConstraints();
3578 *w
= constr
->width
.GetValue();
3579 *h
= constr
->height
.GetValue();
3582 GetClientSize(w
, h
);
3585 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3587 wxLayoutConstraints
*constr
= GetConstraints();
3590 *x
= constr
->left
.GetValue();
3591 *y
= constr
->top
.GetValue();