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 wxWindow::wxWindow()
1314 m_widget
= (GtkWidget
*) NULL
;
1315 m_wxwindow
= (GtkWidget
*) NULL
;
1316 m_parent
= (wxWindow
*) NULL
;
1317 m_children
.DeleteContents( FALSE
);
1330 m_eventHandler
= this;
1331 m_windowValidator
= (wxValidator
*) NULL
;
1335 m_cursor
= (wxCursor
*) NULL
;
1336 m_font
= *wxSWISS_FONT
;
1338 m_windowName
= "noname";
1340 m_constraints
= (wxLayoutConstraints
*) NULL
;
1341 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1342 m_windowSizer
= (wxSizer
*) NULL
;
1343 m_sizerParent
= (wxWindow
*) NULL
;
1344 m_autoLayout
= FALSE
;
1348 m_needParent
= TRUE
;
1350 m_hasScrolling
= FALSE
;
1351 m_isScrolling
= FALSE
;
1352 m_hAdjust
= (GtkAdjustment
*) NULL
;
1353 m_vAdjust
= (GtkAdjustment
*) NULL
;
1354 m_oldHorizontalPos
= 0.0;
1355 m_oldVerticalPos
= 0.0;
1360 #if wxUSE_DRAG_AND_DROP
1361 m_dropTarget
= (wxDropTarget
*) NULL
;
1364 m_scrollGC
= (GdkGC
*) NULL
;
1365 m_widgetStyle
= (GtkStyle
*) NULL
;
1367 m_insertCallback
= wxInsertChildInWindow
;
1369 m_clientObject
= (wxClientData
*) NULL
;
1370 m_clientData
= NULL
;
1372 m_isStaticBox
= FALSE
;
1373 m_acceptsFocus
= FALSE
;
1376 m_toolTip
= (wxToolTip
*) NULL
;
1377 #endif // wxUSE_TOOLTIPS
1380 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1381 const wxPoint
&pos
, const wxSize
&size
,
1382 long style
, const wxString
&name
)
1384 m_insertCallback
= wxInsertChildInWindow
;
1385 Create( parent
, id
, pos
, size
, style
, name
);
1388 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1389 const wxPoint
&pos
, const wxSize
&size
,
1390 long style
, const wxString
&name
)
1394 m_needParent
= TRUE
;
1396 PreCreation( parent
, id
, pos
, size
, style
, name
);
1398 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1399 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1402 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1405 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1408 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1409 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1412 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1413 scroll_class
->scrollbar_spacing
= 0;
1415 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1417 m_oldHorizontalPos
= 0.0;
1418 m_oldVerticalPos
= 0.0;
1420 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1421 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1423 m_wxwindow
= gtk_myfixed_new();
1426 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1429 #ifdef NEW_GTK_SCROLL_CODE
1430 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1431 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1433 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1434 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1438 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1441 if (m_windowStyle
& wxRAISED_BORDER
)
1443 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1445 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1447 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1451 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1454 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1456 /* we now allow a window to get the focus as long as it
1457 doesn't have any children. */
1458 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1459 m_acceptsFocus
= FALSE
;
1463 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1464 m_acceptsFocus
= TRUE
;
1467 // shut the viewport up
1468 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1469 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1471 // I _really_ don't want scrollbars in the beginning
1472 m_vAdjust
->lower
= 0.0;
1473 m_vAdjust
->upper
= 1.0;
1474 m_vAdjust
->value
= 0.0;
1475 m_vAdjust
->step_increment
= 1.0;
1476 m_vAdjust
->page_increment
= 1.0;
1477 m_vAdjust
->page_size
= 5.0;
1478 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1479 m_hAdjust
->lower
= 0.0;
1480 m_hAdjust
->upper
= 1.0;
1481 m_hAdjust
->value
= 0.0;
1482 m_hAdjust
->step_increment
= 1.0;
1483 m_hAdjust
->page_increment
= 1.0;
1484 m_hAdjust
->page_size
= 5.0;
1485 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1487 // these handlers block mouse events to any window during scrolling
1488 // such as motion events and prevent GTK and wxWindows from fighting
1489 // over where the slider should be
1491 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1492 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1494 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1495 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1497 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1498 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1500 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1501 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1503 // these handers het notified when screen updates are required either when
1504 // scrolling or when the window size (and therefore scrollbar configuration)
1507 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1508 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1509 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1510 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1512 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1513 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1514 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1515 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1517 gtk_widget_show( m_wxwindow
);
1519 if (m_parent
) m_parent
->AddChild( this );
1521 (m_parent
->m_insertCallback
)( m_parent
, this );
1530 wxWindow::~wxWindow()
1534 #if wxUSE_DRAG_AND_DROP
1537 delete m_dropTarget
;
1538 m_dropTarget
= (wxDropTarget
*) NULL
;
1546 m_toolTip
= (wxToolTip
*) NULL
;
1548 #endif // wxUSE_TOOLTIPS
1550 if (m_widget
) Show( FALSE
);
1554 if (m_parent
) m_parent
->RemoveChild( this );
1556 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1558 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1560 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1562 if (m_widget
) gtk_widget_destroy( m_widget
);
1564 if (m_cursor
) delete m_cursor
;
1566 DeleteRelatedConstraints();
1569 /* This removes any dangling pointers to this window
1570 * in other windows' constraintsInvolvedIn lists. */
1571 UnsetConstraints(m_constraints
);
1572 delete m_constraints
;
1573 m_constraints
= (wxLayoutConstraints
*) NULL
;
1578 delete m_windowSizer
;
1579 m_windowSizer
= (wxSizer
*) NULL
;
1581 /* If this is a child of a sizer, remove self from parent */
1582 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1584 /* Just in case the window has been Closed, but
1585 * we're then deleting immediately: don't leave
1586 * dangling pointers. */
1587 wxPendingDelete
.DeleteObject(this);
1589 /* Just in case we've loaded a top-level window via
1590 * wxWindow::LoadNativeDialog but we weren't a dialog
1592 wxTopLevelWindows
.DeleteObject(this);
1594 if (m_windowValidator
) delete m_windowValidator
;
1596 if (m_clientObject
) delete m_clientObject
;
1599 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1600 const wxPoint
&pos
, const wxSize
&size
,
1601 long style
, const wxString
&name
)
1603 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1605 m_widget
= (GtkWidget
*) NULL
;
1606 m_wxwindow
= (GtkWidget
*) NULL
;
1609 m_children
.DeleteContents( FALSE
);
1612 if (m_width
== -1) m_width
= 20;
1614 if (m_height
== -1) m_height
= 20;
1619 if (!m_needParent
) /* some reasonable defaults */
1623 m_x
= (gdk_screen_width () - m_width
) / 2;
1624 if (m_x
< 10) m_x
= 10;
1628 m_y
= (gdk_screen_height () - m_height
) / 2;
1629 if (m_y
< 10) m_y
= 10;
1640 m_eventHandler
= this;
1642 m_windowId
= id
== -1 ? wxNewId() : id
;
1646 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1647 m_font
= *wxSWISS_FONT
;
1648 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1649 m_foregroundColour
= *wxBLACK
;
1650 m_windowStyle
= style
;
1651 m_windowName
= name
;
1653 m_constraints
= (wxLayoutConstraints
*) NULL
;
1654 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1655 m_windowSizer
= (wxSizer
*) NULL
;
1656 m_sizerParent
= (wxWindow
*) NULL
;
1657 m_autoLayout
= FALSE
;
1659 m_hasScrolling
= FALSE
;
1660 m_isScrolling
= FALSE
;
1661 m_hAdjust
= (GtkAdjustment
*) NULL
;
1662 m_vAdjust
= (GtkAdjustment
*) NULL
;
1663 m_oldHorizontalPos
= 0.0;
1664 m_oldVerticalPos
= 0.0;
1669 #if wxUSE_DRAG_AND_DROP
1670 m_dropTarget
= (wxDropTarget
*) NULL
;
1673 m_windowValidator
= (wxValidator
*) NULL
;
1674 m_scrollGC
= (GdkGC
*) NULL
;
1675 m_widgetStyle
= (GtkStyle
*) NULL
;
1677 m_clientObject
= (wxClientData
*)NULL
;
1678 m_clientData
= NULL
;
1680 m_isStaticBox
= FALSE
;
1683 m_toolTip
= (wxToolTip
*) NULL
;
1684 #endif // wxUSE_TOOLTIPS
1687 void wxWindow::PostCreation()
1689 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1693 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1694 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1696 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1697 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1700 ConnectWidget( GetConnectWidget() );
1702 /* we force the creation of wxFrame and wxDialog in the respective code */
1703 if (m_parent
) gtk_widget_realize( m_widget
);
1705 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1707 SetCursor( *wxSTANDARD_CURSOR
);
1712 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1714 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1715 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1717 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1718 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1720 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1721 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1723 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1724 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1726 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1727 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1729 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1730 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1732 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1733 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1735 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1736 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1738 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1739 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1742 bool wxWindow::HasVMT()
1747 bool wxWindow::Close( bool force
)
1749 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1751 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1752 event
.SetEventObject(this);
1753 event
.SetCanVeto(!force
);
1755 /* return FALSE if window wasn't closed because the application vetoed the
1757 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1760 bool wxWindow::Destroy()
1762 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1769 bool wxWindow::DestroyChildren()
1772 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1775 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1778 if (m_children
.Member(child
)) delete node
;
1784 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1786 // are we to set fonts here ?
1789 wxPoint
wxWindow::GetClientAreaOrigin() const
1791 return wxPoint(0,0);
1794 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1796 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1798 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1804 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1806 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1807 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1809 if (m_resizing
) return; /* I don't like recursions */
1812 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1814 /* don't set the size for children of wxNotebook, just take the values. */
1822 int old_width
= m_width
;
1823 int old_height
= m_height
;
1825 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1827 if (x
!= -1) m_x
= x
;
1828 if (y
!= -1) m_y
= y
;
1829 if (width
!= -1) m_width
= width
;
1830 if (height
!= -1) m_height
= height
;
1840 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1842 if (width
== -1) m_width
= 80;
1845 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1847 if (height
== -1) m_height
= 26;
1850 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1851 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1852 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1853 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1855 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1857 /* the default button has a border around it */
1860 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1861 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border
);
1863 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1867 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1868 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1870 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1871 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1877 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1878 event
.SetEventObject( this );
1879 GetEventHandler()->ProcessEvent( event
);
1884 void wxWindow::OnInternalIdle()
1889 void wxWindow::GetSize( int *width
, int *height
) const
1891 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1893 if (width
) (*width
) = m_width
;
1894 if (height
) (*height
) = m_height
;
1897 void wxWindow::DoSetClientSize( int width
, int height
)
1899 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1903 SetSize( width
, height
);
1910 if (!m_hasScrolling
)
1912 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1914 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1915 (m_windowStyle
& wxSUNKEN_BORDER
))
1917 dw
+= 2 * window_class
->xthickness
;
1918 dh
+= 2 * window_class
->ythickness
;
1923 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1924 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1926 #ifdef NEW_GTK_SCROLL_CODE
1927 GtkWidget
*viewport
= scroll_window
->child
;
1929 GtkWidget
*viewport
= scroll_window
->viewport
;
1932 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1934 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1935 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1937 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1938 (m_windowStyle
& wxSUNKEN_BORDER
))
1940 dw
+= 2 * viewport_class
->xthickness
;
1941 dh
+= 2 * viewport_class
->ythickness
;
1944 if (scroll_window
->vscrollbar_visible
)
1946 dw
+= vscrollbar
->allocation
.width
;
1947 dw
+= scroll_class
->scrollbar_spacing
;
1950 if (scroll_window
->hscrollbar_visible
)
1952 dh
+= hscrollbar
->allocation
.height
;
1953 dw
+= scroll_class
->scrollbar_spacing
;
1957 SetSize( width
+dw
, height
+dh
);
1961 void wxWindow::GetClientSize( int *width
, int *height
) const
1963 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1967 if (width
) (*width
) = m_width
;
1968 if (height
) (*height
) = m_height
;
1975 if (!m_hasScrolling
)
1977 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1979 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1980 (m_windowStyle
& wxSUNKEN_BORDER
))
1982 dw
+= 2 * window_class
->xthickness
;
1983 dh
+= 2 * window_class
->ythickness
;
1988 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1989 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1991 #ifdef NEW_GTK_SCROLL_CODE
1992 GtkWidget
*viewport
= scroll_window
->child
;
1994 GtkWidget
*viewport
= scroll_window
->viewport
;
1997 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1999 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2000 (m_windowStyle
& wxSUNKEN_BORDER
))
2002 dw
+= 2 * viewport_class
->xthickness
;
2003 dh
+= 2 * viewport_class
->ythickness
;
2006 if (scroll_window
->vscrollbar_visible
)
2008 // dw += vscrollbar->allocation.width;
2009 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
2010 dw
+= scroll_class
->scrollbar_spacing
;
2013 if (scroll_window
->hscrollbar_visible
)
2015 // dh += hscrollbar->allocation.height;
2017 dh
+= scroll_class
->scrollbar_spacing
;
2021 if (width
) (*width
) = m_width
- dw
;
2022 if (height
) (*height
) = m_height
- dh
;
2026 void wxWindow::GetPosition( int *x
, int *y
) const
2028 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2034 void wxWindow::ClientToScreen( int *x
, int *y
)
2036 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2038 GdkWindow
*source
= (GdkWindow
*) NULL
;
2040 source
= m_wxwindow
->window
;
2042 source
= m_widget
->window
;
2046 gdk_window_get_origin( source
, &org_x
, &org_y
);
2050 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2052 org_x
+= m_widget
->allocation
.x
;
2053 org_y
+= m_widget
->allocation
.y
;
2057 wxPoint
pt(GetClientAreaOrigin());
2065 void wxWindow::ScreenToClient( int *x
, int *y
)
2067 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2069 GdkWindow
*source
= (GdkWindow
*) NULL
;
2071 source
= m_wxwindow
->window
;
2073 source
= m_widget
->window
;
2077 gdk_window_get_origin( source
, &org_x
, &org_y
);
2081 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2083 org_x
+= m_widget
->allocation
.x
;
2084 org_y
+= m_widget
->allocation
.y
;
2088 wxPoint
pt(GetClientAreaOrigin());
2096 void wxWindow::Centre( int direction
)
2098 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2107 m_parent
->GetSize( &p_w
, &p_h
);
2108 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2109 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2113 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2114 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2120 void wxWindow::Fit()
2122 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2126 wxNode
*node
= m_children
.First();
2129 wxWindow
*win
= (wxWindow
*)node
->Data();
2131 win
->GetPosition(&wx
, &wy
);
2132 win
->GetSize(&ww
, &wh
);
2133 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2134 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2136 node
= node
->Next();
2139 SetClientSize(maxX
+ 7, maxY
+ 14);
2142 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2144 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2152 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2154 // if (GetAutoLayout()) Layout();
2157 bool wxWindow::Show( bool show
)
2159 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2161 if (show
== m_isShown
) return TRUE
;
2164 gtk_widget_show( m_widget
);
2166 gtk_widget_hide( m_widget
);
2173 void wxWindow::Enable( bool enable
)
2175 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2177 m_isEnabled
= enable
;
2179 gtk_widget_set_sensitive( m_widget
, enable
);
2180 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2183 int wxWindow::GetCharHeight() const
2185 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2187 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2189 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2191 return font
->ascent
+ font
->descent
;
2194 int wxWindow::GetCharWidth() const
2196 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2198 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2200 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2202 return gdk_string_width( font
, "H" );
2205 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2206 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2208 wxFont fontToUse
= m_font
;
2209 if (theFont
) fontToUse
= *theFont
;
2211 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2213 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2214 if (x
) (*x
) = gdk_string_width( font
, string
);
2215 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2216 if (descent
) (*descent
) = font
->descent
;
2217 if (externalLeading
) (*externalLeading
) = 0; // ??
2220 void wxWindow::MakeModal( bool modal
)
2224 // Disable all other windows
2225 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2227 wxNode
*node
= wxTopLevelWindows
.First();
2230 wxWindow
*win
= (wxWindow
*)node
->Data();
2231 if (win
!= this) win
->Enable(!modal
);
2233 node
= node
->Next();
2238 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2240 event
.SetEventType( wxEVT_CHAR
);
2242 if (!GetEventHandler()->ProcessEvent( event
))
2248 void wxWindow::SetFocus()
2250 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2252 GtkWidget
*connect_widget
= GetConnectWidget();
2255 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2257 gtk_widget_grab_focus (connect_widget
);
2259 else if (GTK_IS_CONTAINER(connect_widget
))
2261 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2269 wxWindow
*wxWindow::FindFocus()
2271 return g_focusWindow
;
2274 bool wxWindow::AcceptsFocus() const
2276 return IsEnabled() && IsShown() && m_acceptsFocus
;
2279 void wxWindow::AddChild( wxWindow
*child
)
2281 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2282 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2284 m_children
.Append( child
);
2287 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2289 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2291 wxWindow
*oldParent
= GetParent();
2293 if (oldParent
) oldParent
->RemoveChild( this );
2295 gtk_widget_unparent( m_widget
);
2299 newParent
->AddChild( this );
2300 (newParent
->m_insertCallback
)( newParent
, this );
2306 void wxWindow::RemoveChild( wxWindow
*child
)
2308 m_children
.DeleteObject( child
);
2309 child
->m_parent
= (wxWindow
*) NULL
;
2312 void wxWindow::SetReturnCode( int retCode
)
2314 m_retCode
= retCode
;
2317 int wxWindow::GetReturnCode()
2322 void wxWindow::Raise()
2324 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2326 if (m_widget
) gdk_window_raise( m_widget
->window
);
2329 void wxWindow::Lower()
2331 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2333 if (m_widget
) gdk_window_lower( m_widget
->window
);
2336 wxEvtHandler
*wxWindow::GetEventHandler() const
2338 return m_eventHandler
;
2341 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2343 m_eventHandler
= handler
;
2346 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2348 handler
->SetNextHandler(GetEventHandler());
2349 SetEventHandler(handler
);
2352 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2354 if (GetEventHandler())
2356 wxEvtHandler
*handlerA
= GetEventHandler();
2357 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2358 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2359 SetEventHandler(handlerB
);
2363 return (wxEvtHandler
*) NULL
;
2369 return (wxEvtHandler
*) NULL
;
2372 wxValidator
*wxWindow::GetValidator()
2374 return m_windowValidator
;
2377 void wxWindow::SetValidator( const wxValidator
& validator
)
2379 if (m_windowValidator
) delete m_windowValidator
;
2380 m_windowValidator
= validator
.Clone();
2381 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2384 void wxWindow::SetClientObject( wxClientData
*data
)
2386 if (m_clientObject
) delete m_clientObject
;
2387 m_clientObject
= data
;
2390 wxClientData
*wxWindow::GetClientObject()
2392 return m_clientObject
;
2395 void wxWindow::SetClientData( void *data
)
2397 m_clientData
= data
;
2400 void *wxWindow::GetClientData()
2402 return m_clientData
;
2405 bool wxWindow::IsBeingDeleted()
2410 void wxWindow::SetId( wxWindowID id
)
2415 wxWindowID
wxWindow::GetId() const
2420 void wxWindow::SetCursor( const wxCursor
&cursor
)
2422 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2426 if (cursor
== *m_cursor
) return;
2431 *m_cursor
= *wxSTANDARD_CURSOR
;
2434 if ((m_widget
) && (m_widget
->window
))
2435 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2437 if ((m_wxwindow
) && (m_wxwindow
->window
))
2438 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2441 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2446 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2448 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2450 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2454 gdk_window_clear_area( m_wxwindow
->window
,
2456 rect
->width
, rect
->height
);
2460 gdk_window_clear( m_wxwindow
->window
);
2467 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2469 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2473 GdkRectangle gdk_rect
;
2474 gdk_rect
.x
= rect
->x
;
2475 gdk_rect
.y
= rect
->y
;
2476 gdk_rect
.width
= rect
->width
;
2477 gdk_rect
.height
= rect
->height
;
2480 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2482 gtk_widget_draw( m_widget
, &gdk_rect
);
2486 wxRegion
wxWindow::GetUpdateRegion() const
2488 return m_updateRegion
;
2491 bool wxWindow::IsExposed( int x
, int y
) const
2493 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2496 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2498 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2501 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2503 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2506 bool wxWindow::IsExposed( const wxRect
& rect
) const
2508 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2511 void wxWindow::Clear()
2513 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2515 if (m_wxwindow
&& m_wxwindow
->window
)
2517 gdk_window_clear( m_wxwindow
->window
);
2522 void wxWindow::SetToolTip( const wxString
&tip
)
2526 m_toolTip
->SetTip( tip
);
2530 SetToolTip( new wxToolTip( tip
) );
2533 // setting empty tooltip text does not remove the tooltip any more for
2534 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2537 void wxWindow::SetToolTip( wxToolTip
*tip
)
2541 m_toolTip
->SetTip( (char*) NULL
);
2548 m_toolTip
->Apply( this );
2551 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2553 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2555 #endif // wxUSE_TOOLTIPS
2557 wxColour
wxWindow::GetBackgroundColour() const
2559 return m_backgroundColour
;
2562 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2564 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2566 if (m_backgroundColour
== colour
) return;
2568 m_backgroundColour
= colour
;
2569 if (!m_backgroundColour
.Ok()) return;
2571 if (m_wxwindow
&& m_wxwindow
->window
)
2573 /* wxMSW doesn't clear the window here. I don't do that
2574 either to provide compatibility. call Clear() to do
2577 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2578 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2581 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2583 if (sysbg
.Red() == colour
.Red() &&
2584 sysbg
.Green() == colour
.Green() &&
2585 sysbg
.Blue() == colour
.Blue())
2587 m_backgroundColour
= wxNullColour
;
2589 m_backgroundColour
= sysbg
;
2597 wxColour
wxWindow::GetForegroundColour() const
2599 return m_foregroundColour
;
2602 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2604 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2606 if (m_foregroundColour
== colour
) return;
2608 m_foregroundColour
= colour
;
2609 if (!m_foregroundColour
.Ok()) return;
2611 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2612 if (sysbg
.Red() == colour
.Red() &&
2613 sysbg
.Green() == colour
.Green() &&
2614 sysbg
.Blue() == colour
.Blue())
2616 m_backgroundColour
= wxNullColour
;
2618 m_backgroundColour
= sysbg
;
2626 GtkStyle
*wxWindow::GetWidgetStyle()
2628 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2632 gtk_widget_get_style( m_widget
) );
2634 return m_widgetStyle
;
2637 void wxWindow::SetWidgetStyle()
2639 GtkStyle
*style
= GetWidgetStyle();
2641 gdk_font_unref( style
->font
);
2642 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2644 if (m_foregroundColour
.Ok())
2646 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2647 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2648 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2649 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2652 if (m_backgroundColour
.Ok())
2654 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2655 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2656 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2657 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2658 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2659 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2660 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2661 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2662 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2666 void wxWindow::ApplyWidgetStyle()
2670 bool wxWindow::Validate()
2672 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2674 wxNode
*node
= m_children
.First();
2677 wxWindow
*child
= (wxWindow
*)node
->Data();
2678 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2682 node
= node
->Next();
2687 bool wxWindow::TransferDataToWindow()
2689 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2691 wxNode
*node
= m_children
.First();
2694 wxWindow
*child
= (wxWindow
*)node
->Data();
2695 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2696 !child
->GetValidator()->TransferToWindow() )
2698 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2701 node
= node
->Next();
2706 bool wxWindow::TransferDataFromWindow()
2708 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2710 wxNode
*node
= m_children
.First();
2713 wxWindow
*child
= (wxWindow
*)node
->Data();
2714 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2718 node
= node
->Next();
2723 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2725 m_acceleratorTable
= accel
;
2728 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2730 TransferDataToWindow();
2733 void wxWindow::InitDialog()
2735 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2737 wxInitDialogEvent
event(GetId());
2738 event
.SetEventObject( this );
2739 GetEventHandler()->ProcessEvent(event
);
2742 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2744 menu
->SetInvokingWindow( win
);
2745 wxNode
*node
= menu
->m_items
.First();
2748 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2749 if (menuitem
->IsSubMenu())
2751 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2753 node
= node
->Next();
2757 static gint gs_pop_x
= 0;
2758 static gint gs_pop_y
= 0;
2760 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2762 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2767 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2769 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2771 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2773 SetInvokingWindow( menu
, this );
2781 GTK_MENU(menu
->m_menu
),
2782 (GtkWidget
*) NULL
, // parent menu shell
2783 (GtkWidget
*) NULL
, // parent menu item
2784 (GtkMenuPositionFunc
) pop_pos_callback
,
2785 (gpointer
) this, // client data
2786 0, // button used to activate it
2787 0 //gs_timeLastClick // the time of activation
2792 #if wxUSE_DRAG_AND_DROP
2794 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2796 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2798 GtkWidget
*dnd_widget
= GetConnectWidget();
2800 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2802 if (m_dropTarget
) delete m_dropTarget
;
2803 m_dropTarget
= dropTarget
;
2805 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2808 wxDropTarget
*wxWindow::GetDropTarget() const
2810 return m_dropTarget
;
2815 GtkWidget
* wxWindow::GetConnectWidget()
2817 GtkWidget
*connect_widget
= m_widget
;
2818 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2820 return connect_widget
;
2823 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2825 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2826 return (window
== m_widget
->window
);
2829 void wxWindow::SetFont( const wxFont
&font
)
2831 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2833 if (((wxFont
*)&font
)->Ok())
2836 m_font
= *wxSWISS_FONT
;
2838 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2839 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2840 sysbg
.Green() == m_backgroundColour
.Green() &&
2841 sysbg
.Blue() == m_backgroundColour
.Blue())
2843 m_backgroundColour
= wxNullColour
;
2845 m_backgroundColour
= sysbg
;
2853 void wxWindow::SetWindowStyleFlag( long flag
)
2855 m_windowStyle
= flag
;
2858 long wxWindow::GetWindowStyleFlag() const
2860 return m_windowStyle
;
2863 void wxWindow::CaptureMouse()
2865 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2867 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2869 GtkWidget
*connect_widget
= GetConnectWidget();
2870 gtk_grab_add( connect_widget
);
2871 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2873 (GDK_BUTTON_PRESS_MASK
|
2874 GDK_BUTTON_RELEASE_MASK
|
2875 GDK_POINTER_MOTION_MASK
),
2882 void wxWindow::ReleaseMouse()
2884 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2886 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2888 GtkWidget
*connect_widget
= GetConnectWidget();
2889 gtk_grab_remove( connect_widget
);
2890 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2891 g_capturing
= FALSE
;
2894 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2898 wxString
wxWindow::GetTitle() const
2900 return (wxString
&)m_windowName
;
2903 wxString
wxWindow::GetLabel() const
2908 void wxWindow::SetName( const wxString
&name
)
2910 m_windowName
= name
;
2913 wxString
wxWindow::GetName() const
2915 return (wxString
&)m_windowName
;
2918 bool wxWindow::IsShown() const
2923 bool wxWindow::IsRetained()
2928 wxWindow
*wxWindow::FindWindow( long id
)
2930 if (id
== m_windowId
) return this;
2931 wxNode
*node
= m_children
.First();
2934 wxWindow
*child
= (wxWindow
*)node
->Data();
2935 wxWindow
*res
= child
->FindWindow( id
);
2936 if (res
) return res
;
2937 node
= node
->Next();
2939 return (wxWindow
*) NULL
;
2942 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2944 if (name
== m_windowName
) return this;
2945 wxNode
*node
= m_children
.First();
2948 wxWindow
*child
= (wxWindow
*)node
->Data();
2949 wxWindow
*res
= child
->FindWindow( name
);
2950 if (res
) return res
;
2951 node
= node
->Next();
2953 return (wxWindow
*) NULL
;
2956 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2957 int range
, bool refresh
)
2959 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2961 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2963 m_hasScrolling
= TRUE
;
2965 if (orient
== wxHORIZONTAL
)
2967 float fpos
= (float)pos
;
2968 float frange
= (float)range
;
2969 float fthumb
= (float)thumbVisible
;
2970 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2971 if (fpos
< 0.0) fpos
= 0.0;
2973 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2974 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2976 SetScrollPos( orient
, pos
, refresh
);
2980 m_oldHorizontalPos
= fpos
;
2982 m_hAdjust
->lower
= 0.0;
2983 m_hAdjust
->upper
= frange
;
2984 m_hAdjust
->value
= fpos
;
2985 m_hAdjust
->step_increment
= 1.0;
2986 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2987 m_hAdjust
->page_size
= fthumb
;
2991 float fpos
= (float)pos
;
2992 float frange
= (float)range
;
2993 float fthumb
= (float)thumbVisible
;
2994 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2995 if (fpos
< 0.0) fpos
= 0.0;
2997 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2998 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3000 SetScrollPos( orient
, pos
, refresh
);
3004 m_oldVerticalPos
= fpos
;
3006 m_vAdjust
->lower
= 0.0;
3007 m_vAdjust
->upper
= frange
;
3008 m_vAdjust
->value
= fpos
;
3009 m_vAdjust
->step_increment
= 1.0;
3010 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3011 m_vAdjust
->page_size
= fthumb
;
3014 if (m_wxwindow
->window
)
3016 if (orient
== wxHORIZONTAL
)
3017 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3019 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3021 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3025 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3027 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3029 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3031 if (orient
== wxHORIZONTAL
)
3033 float fpos
= (float)pos
;
3034 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3035 if (fpos
< 0.0) fpos
= 0.0;
3036 m_oldHorizontalPos
= fpos
;
3038 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3039 m_hAdjust
->value
= fpos
;
3043 float fpos
= (float)pos
;
3044 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3045 if (fpos
< 0.0) fpos
= 0.0;
3046 m_oldVerticalPos
= fpos
;
3048 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3049 m_vAdjust
->value
= fpos
;
3054 if (m_wxwindow
->window
)
3056 if (orient
== wxHORIZONTAL
)
3057 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3059 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3064 int wxWindow::GetScrollThumb( int orient
) const
3066 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3068 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3070 if (orient
== wxHORIZONTAL
)
3071 return (int)(m_hAdjust
->page_size
+0.5);
3073 return (int)(m_vAdjust
->page_size
+0.5);
3076 int wxWindow::GetScrollPos( int orient
) const
3078 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3080 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3082 if (orient
== wxHORIZONTAL
)
3083 return (int)(m_hAdjust
->value
+0.5);
3085 return (int)(m_vAdjust
->value
+0.5);
3088 int wxWindow::GetScrollRange( int orient
) const
3090 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3092 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3094 if (orient
== wxHORIZONTAL
)
3095 return (int)(m_hAdjust
->upper
+0.5);
3097 return (int)(m_vAdjust
->upper
+0.5);
3100 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3102 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3104 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3108 GetClientSize( &cw
, &ch
);
3110 int w
= cw
- abs(dx
);
3111 int h
= ch
- abs(dy
);
3112 if ((h
< 0) || (w
< 0))
3119 if (dx
< 0) s_x
= -dx
;
3120 if (dy
< 0) s_y
= -dy
;
3123 if (dx
> 0) d_x
= dx
;
3124 if (dy
> 0) d_y
= dy
;
3128 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3129 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3132 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3133 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3136 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3137 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3138 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3139 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3141 Refresh( TRUE
, &rect
);
3144 //-------------------------------------------------------------------------------------
3146 //-------------------------------------------------------------------------------------
3148 wxLayoutConstraints
*wxWindow::GetConstraints() const
3150 return m_constraints
;
3153 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3157 UnsetConstraints(m_constraints
);
3158 delete m_constraints
;
3160 m_constraints
= constraints
;
3163 // Make sure other windows know they're part of a 'meaningful relationship'
3164 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3165 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3166 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3167 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3168 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3169 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3170 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3171 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3172 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3173 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3174 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3175 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3176 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3177 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3178 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3179 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3185 void wxWindow::SetAutoLayout( bool autoLayout
)
3187 m_autoLayout
= autoLayout
;
3190 bool wxWindow::GetAutoLayout() const
3192 return m_autoLayout
;
3195 wxSizer
*wxWindow::GetSizer() const
3197 return m_windowSizer
;
3200 void wxWindow::SetSizerParent( wxWindow
*win
)
3202 m_sizerParent
= win
;
3205 wxWindow
*wxWindow::GetSizerParent() const
3207 return m_sizerParent
;
3210 // This removes any dangling pointers to this window
3211 // in other windows' constraintsInvolvedIn lists.
3212 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3216 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3217 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3218 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3219 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3220 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3221 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3222 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3223 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3224 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3225 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3226 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3227 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3228 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3229 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3230 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3231 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3235 // Back-pointer to other windows we're involved with, so if we delete
3236 // this window, we must delete any constraints we're involved with.
3237 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3239 if (!m_constraintsInvolvedIn
)
3240 m_constraintsInvolvedIn
= new wxList
;
3241 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3242 m_constraintsInvolvedIn
->Append(otherWin
);
3245 // REMOVE back-pointer to other windows we're involved with.
3246 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3248 if (m_constraintsInvolvedIn
)
3249 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3252 // Reset any constraints that mention this window
3253 void wxWindow::DeleteRelatedConstraints()
3255 if (m_constraintsInvolvedIn
)
3257 wxNode
*node
= m_constraintsInvolvedIn
->First();
3260 wxWindow
*win
= (wxWindow
*)node
->Data();
3261 wxNode
*next
= node
->Next();
3262 wxLayoutConstraints
*constr
= win
->GetConstraints();
3264 // Reset any constraints involving this window
3267 constr
->left
.ResetIfWin((wxWindow
*)this);
3268 constr
->top
.ResetIfWin((wxWindow
*)this);
3269 constr
->right
.ResetIfWin((wxWindow
*)this);
3270 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3271 constr
->width
.ResetIfWin((wxWindow
*)this);
3272 constr
->height
.ResetIfWin((wxWindow
*)this);
3273 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3274 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3279 delete m_constraintsInvolvedIn
;
3280 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3284 void wxWindow::SetSizer(wxSizer
*sizer
)
3286 m_windowSizer
= sizer
;
3288 sizer
->SetSizerParent((wxWindow
*)this);
3295 bool wxWindow::Layout()
3297 if (GetConstraints())
3300 GetClientSize(&w
, &h
);
3301 GetConstraints()->width
.SetValue(w
);
3302 GetConstraints()->height
.SetValue(h
);
3305 // If top level (one sizer), evaluate the sizer's constraints.
3309 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3310 GetSizer()->LayoutPhase1(&noChanges
);
3311 GetSizer()->LayoutPhase2(&noChanges
);
3312 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3317 // Otherwise, evaluate child constraints
3318 ResetConstraints(); // Mark all constraints as unevaluated
3319 DoPhase(1); // Just one phase need if no sizers involved
3321 SetConstraintSizes(); // Recursively set the real window sizes
3327 // Do a phase of evaluating constraints:
3328 // the default behaviour. wxSizers may do a similar
3329 // thing, but also impose their own 'constraints'
3330 // and order the evaluation differently.
3331 bool wxWindow::LayoutPhase1(int *noChanges
)
3333 wxLayoutConstraints
*constr
= GetConstraints();
3336 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3342 bool wxWindow::LayoutPhase2(int *noChanges
)
3352 // Do a phase of evaluating child constraints
3353 bool wxWindow::DoPhase(int phase
)
3355 int noIterations
= 0;
3356 int maxIterations
= 500;
3360 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3364 wxNode
*node
= m_children
.First();
3367 wxWindow
*child
= (wxWindow
*)node
->Data();
3368 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3370 wxLayoutConstraints
*constr
= child
->GetConstraints();
3373 if (succeeded
.Member(child
))
3378 int tempNoChanges
= 0;
3379 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3380 noChanges
+= tempNoChanges
;
3383 succeeded
.Append(child
);
3388 node
= node
->Next();
3395 void wxWindow::ResetConstraints()
3397 wxLayoutConstraints
*constr
= GetConstraints();
3400 constr
->left
.SetDone(FALSE
);
3401 constr
->top
.SetDone(FALSE
);
3402 constr
->right
.SetDone(FALSE
);
3403 constr
->bottom
.SetDone(FALSE
);
3404 constr
->width
.SetDone(FALSE
);
3405 constr
->height
.SetDone(FALSE
);
3406 constr
->centreX
.SetDone(FALSE
);
3407 constr
->centreY
.SetDone(FALSE
);
3409 wxNode
*node
= m_children
.First();
3412 wxWindow
*win
= (wxWindow
*)node
->Data();
3413 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3414 win
->ResetConstraints();
3415 node
= node
->Next();
3419 // Need to distinguish between setting the 'fake' size for
3420 // windows and sizers, and setting the real values.
3421 void wxWindow::SetConstraintSizes(bool recurse
)
3423 wxLayoutConstraints
*constr
= GetConstraints();
3424 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3425 constr
->width
.GetDone() && constr
->height
.GetDone())
3427 int x
= constr
->left
.GetValue();
3428 int y
= constr
->top
.GetValue();
3429 int w
= constr
->width
.GetValue();
3430 int h
= constr
->height
.GetValue();
3432 // If we don't want to resize this window, just move it...
3433 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3434 (constr
->height
.GetRelationship() != wxAsIs
))
3436 // Calls Layout() recursively. AAAGH. How can we stop that.
3437 // Simply take Layout() out of non-top level OnSizes.
3438 SizerSetSize(x
, y
, w
, h
);
3447 char *windowClass
= this->GetClassInfo()->GetClassName();
3450 if (GetName() == "")
3451 winName
= "unnamed";
3453 winName
= GetName();
3454 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3455 (const char *)windowClass
,
3456 (const char *)winName
);
3457 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3458 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3459 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3460 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3461 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3466 wxNode
*node
= m_children
.First();
3469 wxWindow
*win
= (wxWindow
*)node
->Data();
3470 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3471 win
->SetConstraintSizes();
3472 node
= node
->Next();
3477 // This assumes that all sizers are 'on' the same
3478 // window, i.e. the parent of this window.
3479 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3481 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3482 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3486 m_sizerParent
->GetPosition(&xp
, &yp
);
3487 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3492 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3496 TransformSizerToActual(&xx
, &yy
);
3497 SetSize(xx
, yy
, w
, h
);
3500 void wxWindow::SizerMove(int x
, int y
)
3504 TransformSizerToActual(&xx
, &yy
);
3508 // Only set the size/position of the constraint (if any)
3509 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3511 wxLayoutConstraints
*constr
= GetConstraints();
3516 constr
->left
.SetValue(x
);
3517 constr
->left
.SetDone(TRUE
);
3521 constr
->top
.SetValue(y
);
3522 constr
->top
.SetDone(TRUE
);
3526 constr
->width
.SetValue(w
);
3527 constr
->width
.SetDone(TRUE
);
3531 constr
->height
.SetValue(h
);
3532 constr
->height
.SetDone(TRUE
);
3537 void wxWindow::MoveConstraint(int x
, int y
)
3539 wxLayoutConstraints
*constr
= GetConstraints();
3544 constr
->left
.SetValue(x
);
3545 constr
->left
.SetDone(TRUE
);
3549 constr
->top
.SetValue(y
);
3550 constr
->top
.SetDone(TRUE
);
3555 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3557 wxLayoutConstraints
*constr
= GetConstraints();
3560 *w
= constr
->width
.GetValue();
3561 *h
= constr
->height
.GetValue();
3567 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3569 wxLayoutConstraints
*constr
= GetConstraints();
3572 *w
= constr
->width
.GetValue();
3573 *h
= constr
->height
.GetValue();
3576 GetClientSize(w
, h
);
3579 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3581 wxLayoutConstraints
*constr
= GetConstraints();
3584 *x
= constr
->left
.GetValue();
3585 *y
= constr
->top
.GetValue();