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;
1084 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1086 wxEventType command
= wxEVT_NULL
;
1088 float line_step
= win
->m_vAdjust
->step_increment
;
1089 float page_step
= win
->m_vAdjust
->page_increment
;
1091 if (win
->m_isScrolling
)
1093 command
= wxEVT_SCROLL_THUMBTRACK
;
1097 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1098 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1099 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1100 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1101 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1102 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1103 else command
= wxEVT_SCROLL_THUMBTRACK
;
1106 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1108 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1109 event
.SetEventObject( win
);
1110 win
->GetEventHandler()->ProcessEvent( event
);
1113 //-----------------------------------------------------------------------------
1114 // "value_changed" from m_hAdjust
1115 //-----------------------------------------------------------------------------
1117 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1119 if (g_blockEventsOnDrag
) return;
1122 printf( "OnHScroll from " );
1123 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1124 printf( win->GetClassInfo()->GetClassName() );
1128 if (!win
->HasVMT()) return;
1130 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1131 if (fabs(diff
) < 0.2) return;
1132 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1134 wxEventType command
= wxEVT_NULL
;
1136 float line_step
= win
->m_hAdjust
->step_increment
;
1137 float page_step
= win
->m_hAdjust
->page_increment
;
1139 if (win
->m_isScrolling
)
1141 command
= wxEVT_SCROLL_THUMBTRACK
;
1145 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1146 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1147 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1148 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1149 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1150 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1151 else command
= wxEVT_SCROLL_THUMBTRACK
;
1154 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1156 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1157 event
.SetEventObject( win
);
1158 win
->GetEventHandler()->ProcessEvent( event
);
1161 //-----------------------------------------------------------------------------
1162 // "changed" from m_vAdjust
1163 //-----------------------------------------------------------------------------
1165 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1167 if (g_blockEventsOnDrag
) return;
1170 printf( "OnVScroll change from " );
1171 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1172 printf( win->GetClassInfo()->GetClassName() );
1176 if (!win
->HasVMT()) return;
1178 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1179 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1181 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1182 event
.SetEventObject( win
);
1183 win
->GetEventHandler()->ProcessEvent( event
);
1186 //-----------------------------------------------------------------------------
1187 // "changed" from m_hAdjust
1188 //-----------------------------------------------------------------------------
1190 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1192 if (g_blockEventsOnDrag
) return;
1195 printf( "OnHScroll change from " );
1196 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1197 printf( win->GetClassInfo()->GetClassName() );
1201 if (!win
->HasVMT()) return;
1203 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1204 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1206 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1207 event
.SetEventObject( win
);
1208 win
->GetEventHandler()->ProcessEvent( event
);
1211 //-----------------------------------------------------------------------------
1212 // "button_press_event" from scrollbar
1213 //-----------------------------------------------------------------------------
1215 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1216 GdkEventButton
*WXUNUSED(gdk_event
),
1219 // don't test here as we can release the mouse while being over
1220 // a different window then the slider
1222 // if (gdk_event->window != widget->slider) return FALSE;
1224 win
->m_isScrolling
= TRUE
;
1225 g_blockEventsOnScroll
= TRUE
;
1230 //-----------------------------------------------------------------------------
1231 // "button_release_event" from scrollbar
1232 //-----------------------------------------------------------------------------
1234 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1235 GdkEventButton
*WXUNUSED(gdk_event
),
1239 // don't test here as we can release the mouse while being over
1240 // a different window then the slider
1242 // if (gdk_event->window != widget->slider) return FALSE;
1244 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1246 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1247 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1249 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1251 win
->m_isScrolling
= FALSE
;
1252 g_blockEventsOnScroll
= FALSE
;
1257 //-----------------------------------------------------------------------------
1258 // InsertChild for wxWindow.
1259 //-----------------------------------------------------------------------------
1261 /* Callback for wxWindow. This very strange beast has to be used because
1262 * C++ has no virtual methods in a constructor. We have to emulate a
1263 * virtual function here as wxNotebook requires a different way to insert
1264 * a child in it. I had opted for creating a wxNotebookPage window class
1265 * which would have made this superfluous (such in the MDI window system),
1266 * but no-one was listening to me... */
1268 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1270 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1271 GTK_WIDGET(child
->m_widget
),
1275 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1279 if (wxIS_KIND_OF(parent
,wxFrame
))
1281 parent
->m_sizeSet
= FALSE
;
1284 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1286 /* we now allow a window to get the focus as long as it
1287 doesn't have any children. */
1288 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1292 //-----------------------------------------------------------------------------
1294 //-----------------------------------------------------------------------------
1296 wxWindow
* wxGetActiveWindow()
1298 return g_focusWindow
;
1301 //-----------------------------------------------------------------------------
1303 //-----------------------------------------------------------------------------
1305 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1307 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1308 EVT_SIZE(wxWindow::OnSize
)
1309 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1310 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1311 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1314 void wxWindow::Init()
1318 m_widget
= (GtkWidget
*) NULL
;
1319 m_wxwindow
= (GtkWidget
*) NULL
;
1320 m_parent
= (wxWindow
*) NULL
;
1321 m_children
.DeleteContents( FALSE
);
1334 m_eventHandler
= this;
1335 m_windowValidator
= (wxValidator
*) NULL
;
1339 m_cursor
= (wxCursor
*) NULL
;
1340 m_font
= *wxSWISS_FONT
;
1342 m_windowName
= "noname";
1344 m_constraints
= (wxLayoutConstraints
*) NULL
;
1345 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1346 m_windowSizer
= (wxSizer
*) NULL
;
1347 m_sizerParent
= (wxWindow
*) NULL
;
1348 m_autoLayout
= FALSE
;
1352 m_needParent
= TRUE
;
1354 m_hasScrolling
= FALSE
;
1355 m_isScrolling
= FALSE
;
1356 m_hAdjust
= (GtkAdjustment
*) NULL
;
1357 m_vAdjust
= (GtkAdjustment
*) NULL
;
1358 m_oldHorizontalPos
= 0.0;
1359 m_oldVerticalPos
= 0.0;
1364 #if wxUSE_DRAG_AND_DROP
1365 m_dropTarget
= (wxDropTarget
*) NULL
;
1368 m_scrollGC
= (GdkGC
*) NULL
;
1369 m_widgetStyle
= (GtkStyle
*) NULL
;
1371 m_insertCallback
= wxInsertChildInWindow
;
1373 m_clientObject
= (wxClientData
*) NULL
;
1374 m_clientData
= NULL
;
1376 m_isStaticBox
= FALSE
;
1377 m_acceptsFocus
= FALSE
;
1380 m_toolTip
= (wxToolTip
*) NULL
;
1381 #endif // wxUSE_TOOLTIPS
1384 wxWindow::wxWindow()
1389 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1390 const wxPoint
&pos
, const wxSize
&size
,
1391 long style
, const wxString
&name
)
1395 Create( parent
, id
, pos
, size
, style
, name
);
1398 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1399 const wxPoint
&pos
, const wxSize
&size
,
1400 long style
, const wxString
&name
)
1402 wxASSERT_MSG( m_isWindow
, "Init() must have been called before!" );
1404 PreCreation( parent
, id
, pos
, size
, style
, name
);
1406 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1407 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1410 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1413 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1416 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1417 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1420 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1421 scroll_class
->scrollbar_spacing
= 0;
1423 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1425 m_oldHorizontalPos
= 0.0;
1426 m_oldVerticalPos
= 0.0;
1428 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1429 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1431 m_wxwindow
= gtk_myfixed_new();
1434 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1437 #ifdef NEW_GTK_SCROLL_CODE
1438 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1439 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1441 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1442 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1446 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1449 if (m_windowStyle
& wxRAISED_BORDER
)
1451 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1453 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1455 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1459 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1462 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1464 /* we now allow a window to get the focus as long as it
1465 doesn't have any children. */
1466 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1467 m_acceptsFocus
= FALSE
;
1471 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1472 m_acceptsFocus
= TRUE
;
1475 // shut the viewport up
1476 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1477 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1479 // I _really_ don't want scrollbars in the beginning
1480 m_vAdjust
->lower
= 0.0;
1481 m_vAdjust
->upper
= 1.0;
1482 m_vAdjust
->value
= 0.0;
1483 m_vAdjust
->step_increment
= 1.0;
1484 m_vAdjust
->page_increment
= 1.0;
1485 m_vAdjust
->page_size
= 5.0;
1486 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1487 m_hAdjust
->lower
= 0.0;
1488 m_hAdjust
->upper
= 1.0;
1489 m_hAdjust
->value
= 0.0;
1490 m_hAdjust
->step_increment
= 1.0;
1491 m_hAdjust
->page_increment
= 1.0;
1492 m_hAdjust
->page_size
= 5.0;
1493 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1495 // these handlers block mouse events to any window during scrolling
1496 // such as motion events and prevent GTK and wxWindows from fighting
1497 // over where the slider should be
1499 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1500 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1502 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1503 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1505 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1506 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1508 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1509 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1511 // these handers het notified when screen updates are required either when
1512 // scrolling or when the window size (and therefore scrollbar configuration)
1515 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1516 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1517 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1518 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1520 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1521 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1522 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1523 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1525 gtk_widget_show( m_wxwindow
);
1527 if (m_parent
) m_parent
->AddChild( this );
1529 (m_parent
->m_insertCallback
)( m_parent
, this );
1538 wxWindow::~wxWindow()
1542 #if wxUSE_DRAG_AND_DROP
1545 delete m_dropTarget
;
1546 m_dropTarget
= (wxDropTarget
*) NULL
;
1554 m_toolTip
= (wxToolTip
*) NULL
;
1556 #endif // wxUSE_TOOLTIPS
1558 if (m_widget
) Show( FALSE
);
1562 if (m_parent
) m_parent
->RemoveChild( this );
1564 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1566 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1568 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1570 if (m_widget
) gtk_widget_destroy( m_widget
);
1572 if (m_cursor
) delete m_cursor
;
1574 DeleteRelatedConstraints();
1577 /* This removes any dangling pointers to this window
1578 * in other windows' constraintsInvolvedIn lists. */
1579 UnsetConstraints(m_constraints
);
1580 delete m_constraints
;
1581 m_constraints
= (wxLayoutConstraints
*) NULL
;
1586 delete m_windowSizer
;
1587 m_windowSizer
= (wxSizer
*) NULL
;
1589 /* If this is a child of a sizer, remove self from parent */
1590 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1592 /* Just in case the window has been Closed, but
1593 * we're then deleting immediately: don't leave
1594 * dangling pointers. */
1595 wxPendingDelete
.DeleteObject(this);
1597 /* Just in case we've loaded a top-level window via
1598 * wxWindow::LoadNativeDialog but we weren't a dialog
1600 wxTopLevelWindows
.DeleteObject(this);
1602 if (m_windowValidator
) delete m_windowValidator
;
1604 if (m_clientObject
) delete m_clientObject
;
1607 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1608 const wxPoint
&pos
, const wxSize
&size
,
1609 long style
, const wxString
&name
)
1611 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1613 m_widget
= (GtkWidget
*) NULL
;
1614 m_wxwindow
= (GtkWidget
*) NULL
;
1617 m_children
.DeleteContents( FALSE
);
1620 if (m_width
== -1) m_width
= 20;
1622 if (m_height
== -1) m_height
= 20;
1627 if (!m_needParent
) /* some reasonable defaults */
1631 m_x
= (gdk_screen_width () - m_width
) / 2;
1632 if (m_x
< 10) m_x
= 10;
1636 m_y
= (gdk_screen_height () - m_height
) / 2;
1637 if (m_y
< 10) m_y
= 10;
1648 m_eventHandler
= this;
1650 m_windowId
= id
== -1 ? wxNewId() : id
;
1654 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1655 m_font
= *wxSWISS_FONT
;
1656 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1657 m_foregroundColour
= *wxBLACK
;
1658 m_windowStyle
= style
;
1659 m_windowName
= name
;
1661 m_constraints
= (wxLayoutConstraints
*) NULL
;
1662 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1663 m_windowSizer
= (wxSizer
*) NULL
;
1664 m_sizerParent
= (wxWindow
*) NULL
;
1665 m_autoLayout
= FALSE
;
1667 m_hasScrolling
= FALSE
;
1668 m_isScrolling
= FALSE
;
1669 m_hAdjust
= (GtkAdjustment
*) NULL
;
1670 m_vAdjust
= (GtkAdjustment
*) NULL
;
1671 m_oldHorizontalPos
= 0.0;
1672 m_oldVerticalPos
= 0.0;
1677 #if wxUSE_DRAG_AND_DROP
1678 m_dropTarget
= (wxDropTarget
*) NULL
;
1681 m_windowValidator
= (wxValidator
*) NULL
;
1682 m_scrollGC
= (GdkGC
*) NULL
;
1683 m_widgetStyle
= (GtkStyle
*) NULL
;
1685 m_clientObject
= (wxClientData
*)NULL
;
1686 m_clientData
= NULL
;
1688 m_isStaticBox
= FALSE
;
1691 m_toolTip
= (wxToolTip
*) NULL
;
1692 #endif // wxUSE_TOOLTIPS
1695 void wxWindow::PostCreation()
1697 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1701 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1702 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1704 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1705 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1708 ConnectWidget( GetConnectWidget() );
1710 /* we force the creation of wxFrame and wxDialog in the respective code */
1711 if (m_parent
) gtk_widget_realize( m_widget
);
1713 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1715 SetCursor( *wxSTANDARD_CURSOR
);
1720 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1722 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1723 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1725 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1726 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1728 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1729 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1731 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1732 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1734 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1735 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1737 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1738 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1740 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1741 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1743 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1744 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1746 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1747 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1750 bool wxWindow::HasVMT()
1755 bool wxWindow::Close( bool force
)
1757 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1759 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1760 event
.SetEventObject(this);
1761 event
.SetCanVeto(!force
);
1763 /* return FALSE if window wasn't closed because the application vetoed the
1765 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1768 bool wxWindow::Destroy()
1770 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1777 bool wxWindow::DestroyChildren()
1780 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1783 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1786 if (m_children
.Member(child
)) delete node
;
1792 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1794 // are we to set fonts here ?
1797 wxPoint
wxWindow::GetClientAreaOrigin() const
1799 return wxPoint(0,0);
1802 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1804 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1806 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1812 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1814 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1815 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1817 if (m_resizing
) return; /* I don't like recursions */
1820 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1822 /* don't set the size for children of wxNotebook, just take the values. */
1830 int old_width
= m_width
;
1831 int old_height
= m_height
;
1833 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1835 if (x
!= -1) m_x
= x
;
1836 if (y
!= -1) m_y
= y
;
1837 if (width
!= -1) m_width
= width
;
1838 if (height
!= -1) m_height
= height
;
1848 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1850 if (width
== -1) m_width
= 80;
1853 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1855 if (height
== -1) m_height
= 26;
1858 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1859 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1860 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1861 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1863 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1865 /* the default button has a border around it */
1868 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1869 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border
);
1871 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1875 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1876 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1878 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1879 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1885 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1886 event
.SetEventObject( this );
1887 GetEventHandler()->ProcessEvent( event
);
1892 void wxWindow::OnInternalIdle()
1897 void wxWindow::GetSize( int *width
, int *height
) const
1899 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1901 if (width
) (*width
) = m_width
;
1902 if (height
) (*height
) = m_height
;
1905 void wxWindow::DoSetClientSize( int width
, int height
)
1907 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1911 SetSize( width
, height
);
1918 if (!m_hasScrolling
)
1920 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1922 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1923 (m_windowStyle
& wxSUNKEN_BORDER
))
1925 dw
+= 2 * window_class
->xthickness
;
1926 dh
+= 2 * window_class
->ythickness
;
1931 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1932 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1934 #ifdef NEW_GTK_SCROLL_CODE
1935 GtkWidget
*viewport
= scroll_window
->child
;
1937 GtkWidget
*viewport
= scroll_window
->viewport
;
1940 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1942 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1943 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1945 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1946 (m_windowStyle
& wxSUNKEN_BORDER
))
1948 dw
+= 2 * viewport_class
->xthickness
;
1949 dh
+= 2 * viewport_class
->ythickness
;
1952 if (scroll_window
->vscrollbar_visible
)
1954 dw
+= vscrollbar
->allocation
.width
;
1955 dw
+= scroll_class
->scrollbar_spacing
;
1958 if (scroll_window
->hscrollbar_visible
)
1960 dh
+= hscrollbar
->allocation
.height
;
1961 dw
+= scroll_class
->scrollbar_spacing
;
1965 SetSize( width
+dw
, height
+dh
);
1969 void wxWindow::GetClientSize( int *width
, int *height
) const
1971 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1975 if (width
) (*width
) = m_width
;
1976 if (height
) (*height
) = m_height
;
1983 if (!m_hasScrolling
)
1985 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1987 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1988 (m_windowStyle
& wxSUNKEN_BORDER
))
1990 dw
+= 2 * window_class
->xthickness
;
1991 dh
+= 2 * window_class
->ythickness
;
1996 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1997 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1999 #ifdef NEW_GTK_SCROLL_CODE
2000 GtkWidget
*viewport
= scroll_window
->child
;
2002 GtkWidget
*viewport
= scroll_window
->viewport
;
2005 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2007 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2008 (m_windowStyle
& wxSUNKEN_BORDER
))
2010 dw
+= 2 * viewport_class
->xthickness
;
2011 dh
+= 2 * viewport_class
->ythickness
;
2014 if (scroll_window
->vscrollbar_visible
)
2016 // dw += vscrollbar->allocation.width;
2017 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
2018 dw
+= scroll_class
->scrollbar_spacing
;
2021 if (scroll_window
->hscrollbar_visible
)
2023 // dh += hscrollbar->allocation.height;
2025 dh
+= scroll_class
->scrollbar_spacing
;
2029 if (width
) (*width
) = m_width
- dw
;
2030 if (height
) (*height
) = m_height
- dh
;
2034 void wxWindow::GetPosition( int *x
, int *y
) const
2036 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2042 void wxWindow::ClientToScreen( int *x
, int *y
)
2044 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2046 GdkWindow
*source
= (GdkWindow
*) NULL
;
2048 source
= m_wxwindow
->window
;
2050 source
= m_widget
->window
;
2054 gdk_window_get_origin( source
, &org_x
, &org_y
);
2058 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2060 org_x
+= m_widget
->allocation
.x
;
2061 org_y
+= m_widget
->allocation
.y
;
2065 wxPoint
pt(GetClientAreaOrigin());
2073 void wxWindow::ScreenToClient( int *x
, int *y
)
2075 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2077 GdkWindow
*source
= (GdkWindow
*) NULL
;
2079 source
= m_wxwindow
->window
;
2081 source
= m_widget
->window
;
2085 gdk_window_get_origin( source
, &org_x
, &org_y
);
2089 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2091 org_x
+= m_widget
->allocation
.x
;
2092 org_y
+= m_widget
->allocation
.y
;
2096 wxPoint
pt(GetClientAreaOrigin());
2104 void wxWindow::Centre( int direction
)
2106 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2115 m_parent
->GetSize( &p_w
, &p_h
);
2116 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2117 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2121 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2122 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2128 void wxWindow::Fit()
2130 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2134 wxNode
*node
= m_children
.First();
2137 wxWindow
*win
= (wxWindow
*)node
->Data();
2139 win
->GetPosition(&wx
, &wy
);
2140 win
->GetSize(&ww
, &wh
);
2141 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2142 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2144 node
= node
->Next();
2147 SetClientSize(maxX
+ 7, maxY
+ 14);
2150 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2152 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2160 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2162 // if (GetAutoLayout()) Layout();
2165 bool wxWindow::Show( bool show
)
2167 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2169 if (show
== m_isShown
) return TRUE
;
2172 gtk_widget_show( m_widget
);
2174 gtk_widget_hide( m_widget
);
2181 void wxWindow::Enable( bool enable
)
2183 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2185 m_isEnabled
= enable
;
2187 gtk_widget_set_sensitive( m_widget
, enable
);
2188 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2191 int wxWindow::GetCharHeight() const
2193 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2195 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2197 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2199 return font
->ascent
+ font
->descent
;
2202 int wxWindow::GetCharWidth() const
2204 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2206 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2208 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2210 return gdk_string_width( font
, "H" );
2213 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2214 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2216 wxFont fontToUse
= m_font
;
2217 if (theFont
) fontToUse
= *theFont
;
2219 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2221 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2222 if (x
) (*x
) = gdk_string_width( font
, string
);
2223 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2224 if (descent
) (*descent
) = font
->descent
;
2225 if (externalLeading
) (*externalLeading
) = 0; // ??
2228 void wxWindow::MakeModal( bool modal
)
2232 // Disable all other windows
2233 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2235 wxNode
*node
= wxTopLevelWindows
.First();
2238 wxWindow
*win
= (wxWindow
*)node
->Data();
2239 if (win
!= this) win
->Enable(!modal
);
2241 node
= node
->Next();
2246 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2248 event
.SetEventType( wxEVT_CHAR
);
2250 if (!GetEventHandler()->ProcessEvent( event
))
2256 void wxWindow::SetFocus()
2258 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2260 GtkWidget
*connect_widget
= GetConnectWidget();
2263 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2265 gtk_widget_grab_focus (connect_widget
);
2267 else if (GTK_IS_CONTAINER(connect_widget
))
2269 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2277 wxWindow
*wxWindow::FindFocus()
2279 return g_focusWindow
;
2282 bool wxWindow::AcceptsFocus() const
2284 return IsEnabled() && IsShown() && m_acceptsFocus
;
2287 void wxWindow::AddChild( wxWindow
*child
)
2289 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2290 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2292 m_children
.Append( child
);
2295 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2297 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2299 wxWindow
*oldParent
= GetParent();
2301 if (oldParent
) oldParent
->RemoveChild( this );
2303 gtk_widget_unparent( m_widget
);
2307 newParent
->AddChild( this );
2308 (newParent
->m_insertCallback
)( newParent
, this );
2314 void wxWindow::RemoveChild( wxWindow
*child
)
2316 m_children
.DeleteObject( child
);
2317 child
->m_parent
= (wxWindow
*) NULL
;
2320 void wxWindow::SetReturnCode( int retCode
)
2322 m_retCode
= retCode
;
2325 int wxWindow::GetReturnCode()
2330 void wxWindow::Raise()
2332 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2334 if (m_widget
) gdk_window_raise( m_widget
->window
);
2337 void wxWindow::Lower()
2339 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2341 if (m_widget
) gdk_window_lower( m_widget
->window
);
2344 wxEvtHandler
*wxWindow::GetEventHandler() const
2346 return m_eventHandler
;
2349 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2351 m_eventHandler
= handler
;
2354 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2356 handler
->SetNextHandler(GetEventHandler());
2357 SetEventHandler(handler
);
2360 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2362 if (GetEventHandler())
2364 wxEvtHandler
*handlerA
= GetEventHandler();
2365 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2366 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2367 SetEventHandler(handlerB
);
2371 return (wxEvtHandler
*) NULL
;
2377 return (wxEvtHandler
*) NULL
;
2380 wxValidator
*wxWindow::GetValidator()
2382 return m_windowValidator
;
2385 void wxWindow::SetValidator( const wxValidator
& validator
)
2387 if (m_windowValidator
) delete m_windowValidator
;
2388 m_windowValidator
= validator
.Clone();
2389 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2392 void wxWindow::SetClientObject( wxClientData
*data
)
2394 if (m_clientObject
) delete m_clientObject
;
2395 m_clientObject
= data
;
2398 wxClientData
*wxWindow::GetClientObject()
2400 return m_clientObject
;
2403 void wxWindow::SetClientData( void *data
)
2405 m_clientData
= data
;
2408 void *wxWindow::GetClientData()
2410 return m_clientData
;
2413 bool wxWindow::IsBeingDeleted()
2418 void wxWindow::SetId( wxWindowID id
)
2423 wxWindowID
wxWindow::GetId() const
2428 void wxWindow::SetCursor( const wxCursor
&cursor
)
2430 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2434 if (cursor
== *m_cursor
) return;
2439 *m_cursor
= *wxSTANDARD_CURSOR
;
2442 if ((m_widget
) && (m_widget
->window
))
2443 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2445 if ((m_wxwindow
) && (m_wxwindow
->window
))
2446 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2449 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2454 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2456 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2458 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2462 gdk_window_clear_area( m_wxwindow
->window
,
2464 rect
->width
, rect
->height
);
2468 gdk_window_clear( m_wxwindow
->window
);
2475 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2477 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2481 GdkRectangle gdk_rect
;
2482 gdk_rect
.x
= rect
->x
;
2483 gdk_rect
.y
= rect
->y
;
2484 gdk_rect
.width
= rect
->width
;
2485 gdk_rect
.height
= rect
->height
;
2488 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2490 gtk_widget_draw( m_widget
, &gdk_rect
);
2494 wxRegion
wxWindow::GetUpdateRegion() const
2496 return m_updateRegion
;
2499 bool wxWindow::IsExposed( int x
, int y
) const
2501 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2504 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2506 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2509 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2511 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2514 bool wxWindow::IsExposed( const wxRect
& rect
) const
2516 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2519 void wxWindow::Clear()
2521 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2523 if (m_wxwindow
&& m_wxwindow
->window
)
2525 gdk_window_clear( m_wxwindow
->window
);
2530 void wxWindow::SetToolTip( const wxString
&tip
)
2534 m_toolTip
->SetTip( tip
);
2538 SetToolTip( new wxToolTip( tip
) );
2541 // setting empty tooltip text does not remove the tooltip any more for
2542 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2545 void wxWindow::SetToolTip( wxToolTip
*tip
)
2549 m_toolTip
->SetTip( (char*) NULL
);
2556 m_toolTip
->Apply( this );
2559 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2561 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2563 #endif // wxUSE_TOOLTIPS
2565 wxColour
wxWindow::GetBackgroundColour() const
2567 return m_backgroundColour
;
2570 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2572 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2574 if (m_backgroundColour
== colour
) return;
2576 m_backgroundColour
= colour
;
2577 if (!m_backgroundColour
.Ok()) return;
2579 if (m_wxwindow
&& m_wxwindow
->window
)
2581 /* wxMSW doesn't clear the window here. I don't do that
2582 either to provide compatibility. call Clear() to do
2585 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2586 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2589 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2591 if (sysbg
.Red() == colour
.Red() &&
2592 sysbg
.Green() == colour
.Green() &&
2593 sysbg
.Blue() == colour
.Blue())
2595 m_backgroundColour
= wxNullColour
;
2597 m_backgroundColour
= sysbg
;
2605 wxColour
wxWindow::GetForegroundColour() const
2607 return m_foregroundColour
;
2610 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2612 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2614 if (m_foregroundColour
== colour
) return;
2616 m_foregroundColour
= colour
;
2617 if (!m_foregroundColour
.Ok()) return;
2619 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2620 if (sysbg
.Red() == colour
.Red() &&
2621 sysbg
.Green() == colour
.Green() &&
2622 sysbg
.Blue() == colour
.Blue())
2624 m_backgroundColour
= wxNullColour
;
2626 m_backgroundColour
= sysbg
;
2634 GtkStyle
*wxWindow::GetWidgetStyle()
2636 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2640 gtk_widget_get_style( m_widget
) );
2642 return m_widgetStyle
;
2645 void wxWindow::SetWidgetStyle()
2647 GtkStyle
*style
= GetWidgetStyle();
2649 gdk_font_unref( style
->font
);
2650 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2652 if (m_foregroundColour
.Ok())
2654 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2655 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2656 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2657 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2660 if (m_backgroundColour
.Ok())
2662 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2663 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2664 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2665 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2666 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2667 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2668 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2669 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2670 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2674 void wxWindow::ApplyWidgetStyle()
2678 bool wxWindow::Validate()
2680 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2682 wxNode
*node
= m_children
.First();
2685 wxWindow
*child
= (wxWindow
*)node
->Data();
2686 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2690 node
= node
->Next();
2695 bool wxWindow::TransferDataToWindow()
2697 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2699 wxNode
*node
= m_children
.First();
2702 wxWindow
*child
= (wxWindow
*)node
->Data();
2703 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2704 !child
->GetValidator()->TransferToWindow() )
2706 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2709 node
= node
->Next();
2714 bool wxWindow::TransferDataFromWindow()
2716 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2718 wxNode
*node
= m_children
.First();
2721 wxWindow
*child
= (wxWindow
*)node
->Data();
2722 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2726 node
= node
->Next();
2731 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2733 m_acceleratorTable
= accel
;
2736 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2738 TransferDataToWindow();
2741 void wxWindow::InitDialog()
2743 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2745 wxInitDialogEvent
event(GetId());
2746 event
.SetEventObject( this );
2747 GetEventHandler()->ProcessEvent(event
);
2750 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2752 menu
->SetInvokingWindow( win
);
2753 wxNode
*node
= menu
->m_items
.First();
2756 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2757 if (menuitem
->IsSubMenu())
2759 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2761 node
= node
->Next();
2765 static gint gs_pop_x
= 0;
2766 static gint gs_pop_y
= 0;
2768 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2770 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2775 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2777 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2779 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2781 SetInvokingWindow( menu
, this );
2789 GTK_MENU(menu
->m_menu
),
2790 (GtkWidget
*) NULL
, // parent menu shell
2791 (GtkWidget
*) NULL
, // parent menu item
2792 (GtkMenuPositionFunc
) pop_pos_callback
,
2793 (gpointer
) this, // client data
2794 0, // button used to activate it
2795 0 //gs_timeLastClick // the time of activation
2800 #if wxUSE_DRAG_AND_DROP
2802 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2804 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2806 GtkWidget
*dnd_widget
= GetConnectWidget();
2808 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2810 if (m_dropTarget
) delete m_dropTarget
;
2811 m_dropTarget
= dropTarget
;
2813 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2816 wxDropTarget
*wxWindow::GetDropTarget() const
2818 return m_dropTarget
;
2823 GtkWidget
* wxWindow::GetConnectWidget()
2825 GtkWidget
*connect_widget
= m_widget
;
2826 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2828 return connect_widget
;
2831 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2833 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2834 return (window
== m_widget
->window
);
2837 void wxWindow::SetFont( const wxFont
&font
)
2839 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2841 if (m_font
== font
) return;
2843 if (((wxFont
*)&font
)->Ok())
2846 m_font
= *wxSWISS_FONT
;
2848 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2849 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2850 sysbg
.Green() == m_backgroundColour
.Green() &&
2851 sysbg
.Blue() == m_backgroundColour
.Blue())
2853 m_backgroundColour
= wxNullColour
;
2855 m_backgroundColour
= sysbg
;
2863 void wxWindow::SetWindowStyleFlag( long flag
)
2865 m_windowStyle
= flag
;
2868 long wxWindow::GetWindowStyleFlag() const
2870 return m_windowStyle
;
2873 void wxWindow::CaptureMouse()
2875 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2877 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2879 GtkWidget
*connect_widget
= GetConnectWidget();
2880 gtk_grab_add( connect_widget
);
2881 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2883 (GDK_BUTTON_PRESS_MASK
|
2884 GDK_BUTTON_RELEASE_MASK
|
2885 GDK_POINTER_MOTION_MASK
),
2892 void wxWindow::ReleaseMouse()
2894 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2896 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2898 GtkWidget
*connect_widget
= GetConnectWidget();
2899 gtk_grab_remove( connect_widget
);
2900 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2901 g_capturing
= FALSE
;
2904 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2908 wxString
wxWindow::GetTitle() const
2910 return (wxString
&)m_windowName
;
2913 wxString
wxWindow::GetLabel() const
2918 void wxWindow::SetName( const wxString
&name
)
2920 m_windowName
= name
;
2923 wxString
wxWindow::GetName() const
2925 return (wxString
&)m_windowName
;
2928 bool wxWindow::IsShown() const
2933 bool wxWindow::IsRetained()
2938 wxWindow
*wxWindow::FindWindow( long id
)
2940 if (id
== m_windowId
) return this;
2941 wxNode
*node
= m_children
.First();
2944 wxWindow
*child
= (wxWindow
*)node
->Data();
2945 wxWindow
*res
= child
->FindWindow( id
);
2946 if (res
) return res
;
2947 node
= node
->Next();
2949 return (wxWindow
*) NULL
;
2952 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2954 if (name
== m_windowName
) return this;
2955 wxNode
*node
= m_children
.First();
2958 wxWindow
*child
= (wxWindow
*)node
->Data();
2959 wxWindow
*res
= child
->FindWindow( name
);
2960 if (res
) return res
;
2961 node
= node
->Next();
2963 return (wxWindow
*) NULL
;
2966 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2967 int range
, bool refresh
)
2969 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2971 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2973 m_hasScrolling
= TRUE
;
2975 if (orient
== wxHORIZONTAL
)
2977 float fpos
= (float)pos
;
2978 float frange
= (float)range
;
2979 float fthumb
= (float)thumbVisible
;
2980 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2981 if (fpos
< 0.0) fpos
= 0.0;
2983 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2984 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2986 SetScrollPos( orient
, pos
, refresh
);
2990 m_oldHorizontalPos
= fpos
;
2992 m_hAdjust
->lower
= 0.0;
2993 m_hAdjust
->upper
= frange
;
2994 m_hAdjust
->value
= fpos
;
2995 m_hAdjust
->step_increment
= 1.0;
2996 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2997 m_hAdjust
->page_size
= fthumb
;
3001 float fpos
= (float)pos
;
3002 float frange
= (float)range
;
3003 float fthumb
= (float)thumbVisible
;
3004 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3005 if (fpos
< 0.0) fpos
= 0.0;
3007 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3008 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3010 SetScrollPos( orient
, pos
, refresh
);
3014 m_oldVerticalPos
= fpos
;
3016 m_vAdjust
->lower
= 0.0;
3017 m_vAdjust
->upper
= frange
;
3018 m_vAdjust
->value
= fpos
;
3019 m_vAdjust
->step_increment
= 1.0;
3020 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3021 m_vAdjust
->page_size
= fthumb
;
3024 if (m_wxwindow
->window
)
3026 if (orient
== wxHORIZONTAL
)
3027 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3029 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3031 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3035 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3037 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3039 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3041 if (orient
== wxHORIZONTAL
)
3043 float fpos
= (float)pos
;
3044 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3045 if (fpos
< 0.0) fpos
= 0.0;
3046 m_oldHorizontalPos
= fpos
;
3048 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3049 m_hAdjust
->value
= fpos
;
3053 float fpos
= (float)pos
;
3054 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3055 if (fpos
< 0.0) fpos
= 0.0;
3056 m_oldVerticalPos
= fpos
;
3058 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3059 m_vAdjust
->value
= fpos
;
3064 if (m_wxwindow
->window
)
3066 if (orient
== wxHORIZONTAL
)
3067 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3069 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3074 int wxWindow::GetScrollThumb( int orient
) const
3076 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3078 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3080 if (orient
== wxHORIZONTAL
)
3081 return (int)(m_hAdjust
->page_size
+0.5);
3083 return (int)(m_vAdjust
->page_size
+0.5);
3086 int wxWindow::GetScrollPos( int orient
) const
3088 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3090 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3092 if (orient
== wxHORIZONTAL
)
3093 return (int)(m_hAdjust
->value
+0.5);
3095 return (int)(m_vAdjust
->value
+0.5);
3098 int wxWindow::GetScrollRange( int orient
) const
3100 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3102 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3104 if (orient
== wxHORIZONTAL
)
3105 return (int)(m_hAdjust
->upper
+0.5);
3107 return (int)(m_vAdjust
->upper
+0.5);
3110 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3112 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3114 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3118 GetClientSize( &cw
, &ch
);
3120 int w
= cw
- abs(dx
);
3121 int h
= ch
- abs(dy
);
3122 if ((h
< 0) || (w
< 0))
3129 if (dx
< 0) s_x
= -dx
;
3130 if (dy
< 0) s_y
= -dy
;
3133 if (dx
> 0) d_x
= dx
;
3134 if (dy
> 0) d_y
= dy
;
3138 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3139 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3142 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3143 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3146 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3147 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3148 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3149 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3151 Refresh( TRUE
, &rect
);
3154 //-------------------------------------------------------------------------------------
3156 //-------------------------------------------------------------------------------------
3158 wxLayoutConstraints
*wxWindow::GetConstraints() const
3160 return m_constraints
;
3163 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3167 UnsetConstraints(m_constraints
);
3168 delete m_constraints
;
3170 m_constraints
= constraints
;
3173 // Make sure other windows know they're part of a 'meaningful relationship'
3174 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3175 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3176 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3177 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3178 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3179 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3180 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3181 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3182 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3183 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3184 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3185 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3186 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3187 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3188 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3189 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3195 void wxWindow::SetAutoLayout( bool autoLayout
)
3197 m_autoLayout
= autoLayout
;
3200 bool wxWindow::GetAutoLayout() const
3202 return m_autoLayout
;
3205 wxSizer
*wxWindow::GetSizer() const
3207 return m_windowSizer
;
3210 void wxWindow::SetSizerParent( wxWindow
*win
)
3212 m_sizerParent
= win
;
3215 wxWindow
*wxWindow::GetSizerParent() const
3217 return m_sizerParent
;
3220 // This removes any dangling pointers to this window
3221 // in other windows' constraintsInvolvedIn lists.
3222 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3226 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3227 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3228 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3229 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3230 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3231 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3232 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3233 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3234 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3235 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3236 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3237 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3238 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3239 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3240 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3241 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3245 // Back-pointer to other windows we're involved with, so if we delete
3246 // this window, we must delete any constraints we're involved with.
3247 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3249 if (!m_constraintsInvolvedIn
)
3250 m_constraintsInvolvedIn
= new wxList
;
3251 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3252 m_constraintsInvolvedIn
->Append(otherWin
);
3255 // REMOVE back-pointer to other windows we're involved with.
3256 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3258 if (m_constraintsInvolvedIn
)
3259 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3262 // Reset any constraints that mention this window
3263 void wxWindow::DeleteRelatedConstraints()
3265 if (m_constraintsInvolvedIn
)
3267 wxNode
*node
= m_constraintsInvolvedIn
->First();
3270 wxWindow
*win
= (wxWindow
*)node
->Data();
3271 wxNode
*next
= node
->Next();
3272 wxLayoutConstraints
*constr
= win
->GetConstraints();
3274 // Reset any constraints involving this window
3277 constr
->left
.ResetIfWin((wxWindow
*)this);
3278 constr
->top
.ResetIfWin((wxWindow
*)this);
3279 constr
->right
.ResetIfWin((wxWindow
*)this);
3280 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3281 constr
->width
.ResetIfWin((wxWindow
*)this);
3282 constr
->height
.ResetIfWin((wxWindow
*)this);
3283 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3284 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3289 delete m_constraintsInvolvedIn
;
3290 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3294 void wxWindow::SetSizer(wxSizer
*sizer
)
3296 m_windowSizer
= sizer
;
3298 sizer
->SetSizerParent((wxWindow
*)this);
3305 bool wxWindow::Layout()
3307 if (GetConstraints())
3310 GetClientSize(&w
, &h
);
3311 GetConstraints()->width
.SetValue(w
);
3312 GetConstraints()->height
.SetValue(h
);
3315 // If top level (one sizer), evaluate the sizer's constraints.
3319 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3320 GetSizer()->LayoutPhase1(&noChanges
);
3321 GetSizer()->LayoutPhase2(&noChanges
);
3322 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3327 // Otherwise, evaluate child constraints
3328 ResetConstraints(); // Mark all constraints as unevaluated
3329 DoPhase(1); // Just one phase need if no sizers involved
3331 SetConstraintSizes(); // Recursively set the real window sizes
3337 // Do a phase of evaluating constraints:
3338 // the default behaviour. wxSizers may do a similar
3339 // thing, but also impose their own 'constraints'
3340 // and order the evaluation differently.
3341 bool wxWindow::LayoutPhase1(int *noChanges
)
3343 wxLayoutConstraints
*constr
= GetConstraints();
3346 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3352 bool wxWindow::LayoutPhase2(int *noChanges
)
3362 // Do a phase of evaluating child constraints
3363 bool wxWindow::DoPhase(int phase
)
3365 int noIterations
= 0;
3366 int maxIterations
= 500;
3370 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3374 wxNode
*node
= m_children
.First();
3377 wxWindow
*child
= (wxWindow
*)node
->Data();
3378 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3380 wxLayoutConstraints
*constr
= child
->GetConstraints();
3383 if (succeeded
.Member(child
))
3388 int tempNoChanges
= 0;
3389 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3390 noChanges
+= tempNoChanges
;
3393 succeeded
.Append(child
);
3398 node
= node
->Next();
3405 void wxWindow::ResetConstraints()
3407 wxLayoutConstraints
*constr
= GetConstraints();
3410 constr
->left
.SetDone(FALSE
);
3411 constr
->top
.SetDone(FALSE
);
3412 constr
->right
.SetDone(FALSE
);
3413 constr
->bottom
.SetDone(FALSE
);
3414 constr
->width
.SetDone(FALSE
);
3415 constr
->height
.SetDone(FALSE
);
3416 constr
->centreX
.SetDone(FALSE
);
3417 constr
->centreY
.SetDone(FALSE
);
3419 wxNode
*node
= m_children
.First();
3422 wxWindow
*win
= (wxWindow
*)node
->Data();
3423 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3424 win
->ResetConstraints();
3425 node
= node
->Next();
3429 // Need to distinguish between setting the 'fake' size for
3430 // windows and sizers, and setting the real values.
3431 void wxWindow::SetConstraintSizes(bool recurse
)
3433 wxLayoutConstraints
*constr
= GetConstraints();
3434 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3435 constr
->width
.GetDone() && constr
->height
.GetDone())
3437 int x
= constr
->left
.GetValue();
3438 int y
= constr
->top
.GetValue();
3439 int w
= constr
->width
.GetValue();
3440 int h
= constr
->height
.GetValue();
3442 // If we don't want to resize this window, just move it...
3443 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3444 (constr
->height
.GetRelationship() != wxAsIs
))
3446 // Calls Layout() recursively. AAAGH. How can we stop that.
3447 // Simply take Layout() out of non-top level OnSizes.
3448 SizerSetSize(x
, y
, w
, h
);
3457 char *windowClass
= this->GetClassInfo()->GetClassName();
3460 if (GetName() == "")
3461 winName
= "unnamed";
3463 winName
= GetName();
3464 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3465 (const char *)windowClass
,
3466 (const char *)winName
);
3467 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3468 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3469 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3470 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3471 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3476 wxNode
*node
= m_children
.First();
3479 wxWindow
*win
= (wxWindow
*)node
->Data();
3480 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3481 win
->SetConstraintSizes();
3482 node
= node
->Next();
3487 // This assumes that all sizers are 'on' the same
3488 // window, i.e. the parent of this window.
3489 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3491 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3492 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3496 m_sizerParent
->GetPosition(&xp
, &yp
);
3497 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3502 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3506 TransformSizerToActual(&xx
, &yy
);
3507 SetSize(xx
, yy
, w
, h
);
3510 void wxWindow::SizerMove(int x
, int y
)
3514 TransformSizerToActual(&xx
, &yy
);
3518 // Only set the size/position of the constraint (if any)
3519 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3521 wxLayoutConstraints
*constr
= GetConstraints();
3526 constr
->left
.SetValue(x
);
3527 constr
->left
.SetDone(TRUE
);
3531 constr
->top
.SetValue(y
);
3532 constr
->top
.SetDone(TRUE
);
3536 constr
->width
.SetValue(w
);
3537 constr
->width
.SetDone(TRUE
);
3541 constr
->height
.SetValue(h
);
3542 constr
->height
.SetDone(TRUE
);
3547 void wxWindow::MoveConstraint(int x
, int y
)
3549 wxLayoutConstraints
*constr
= GetConstraints();
3554 constr
->left
.SetValue(x
);
3555 constr
->left
.SetDone(TRUE
);
3559 constr
->top
.SetValue(y
);
3560 constr
->top
.SetDone(TRUE
);
3565 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3567 wxLayoutConstraints
*constr
= GetConstraints();
3570 *w
= constr
->width
.GetValue();
3571 *h
= constr
->height
.GetValue();
3577 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3579 wxLayoutConstraints
*constr
= GetConstraints();
3582 *w
= constr
->width
.GetValue();
3583 *h
= constr
->height
.GetValue();
3586 GetClientSize(w
, h
);
3589 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3591 wxLayoutConstraints
*constr
= GetConstraints();
3594 *x
= constr
->left
.GetValue();
3595 *y
= constr
->top
.GetValue();