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"
24 #if wxUSE_DRAG_AND_DROP
28 #include "wx/tooltip.h"
31 #include "wx/statusbr.h"
33 #include "wx/settings.h"
40 #include "gdk/gdkprivate.h"
41 #include "gdk/gdkkeysyms.h"
42 #include "wx/gtk/win_gtk.h"
44 //-----------------------------------------------------------------------------
45 // documentation on internals
46 //-----------------------------------------------------------------------------
49 I have been asked several times about writing some documentation about
50 the GTK port of wxWindows, especially its internal structures. Obviously,
51 you cannot understand wxGTK without knowing a little about the GTK, but
52 some more information about what the wxWindow, which is the base class
53 for all other window classes, does seems required as well.
55 What does wxWindow do? It contains the common interface for the following
56 jobs of its descendants:
58 1) Define the rudimentary behaviour common to all window classes, such as
59 resizing, intercepting user input (so as to make it possible to use these
60 events for special purposes in a derived class), window names etc.
62 2) Provide the possibility to contain and manage children, if the derived
63 class is allowed to contain children, which holds true for those window
64 classes which do not display a native GTK widget. To name them, these
65 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
66 work classes are a special case and are handled a bit differently from
67 the rest. The same holds true for the wxNotebook class.
69 3) Provide the possibility to draw into a client area of a window. This,
70 too, only holds true for classes that do not display a native GTK widget
73 4) Provide the entire mechanism for scrolling widgets. This actual inter-
74 face for this is usually in wxScrolledWindow, but the GTK implementation
77 5) A multitude of helper or extra methods for special purposes, such as
78 Drag'n'Drop, managing validators etc.
80 Normally one might expect, that one wxWindows window would always correspond
81 to one GTK widget. Under GTK, there is no such allround widget that has all
82 the functionality. Moreover, the GTK defines a client area as a different
83 widget from the actual widget you are handling. Last but not least some
84 special classes (e.g. wxFrame) handle different categories of widgets and
85 still have the possibility to draw something in the client area.
86 It was therefore required to write a special purpose GTK widget, that would
87 represent a client area in the sense of wxWindows capable to do the jobs
88 2), 3) and 4). I have written this class and it resides in win_gtk.c of
91 All windows must have a widget, with which they interact with other under-
92 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
93 thw wxWindow class has a member variable called m_widget which holds a
94 pointer to this widget. When the window class represents a GTK native widget,
95 this is (in most cases) the only GTK widget the class manages. E.g. the
96 wxStatitText class handles only a GtkLabel widget a pointer to which you
97 can find in m_widget (defined in wxWindow)
99 When the class has a client area for drawing into and for containing children
100 it has to handle the client area widget (of the type GtkMyFixed, defined in
101 win_gtk.c), but there could be any number of widgets, handled by a class
102 The common rule for all windows is only, that the widget that interacts with
103 the rest of GTK must be referenced in m_widget and all other widgets must be
104 children of this widget on the GTK level. The top-most widget, which also
105 represents the client area, must be in the m_wxwindow field and must be of
108 As I said, the window classes that display a GTK native widget only have
109 one widget, so in the case of e.g. the wxButton class m_widget holds a
110 pointer to a GtkButton widget. But windows with client areas (for drawing
111 and children) have a m_widget field that is a pointer to a GtkScrolled-
112 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
113 one is (in the GTK sense) a child of the GtkScrolledWindow.
115 If the m_wxwindow field is set, then all input to this widget is inter-
116 cepted and sent to the wxWindows class. If not, all input to the widget
117 that gets pointed to by m_widget gets intercepted and sent to the class.
121 //-------------------------------------------------------------------------
122 // conditional compilation
123 //-------------------------------------------------------------------------
125 #if (GTK_MINOR_VERSION == 1)
126 #if (GTK_MICRO_VERSION >= 5)
127 #define NEW_GTK_SCROLL_CODE
131 //-----------------------------------------------------------------------------
133 //-----------------------------------------------------------------------------
137 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
138 GdkEvent
*WXUNUSED(event
),
141 printf( "FOCUS NOW AT: " );
148 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
156 char *s
= new char[tmp
.Length()+1];
158 strcpy( s
, WXSTRINGCAST tmp
);
160 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
161 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
166 //-----------------------------------------------------------------------------
168 //-----------------------------------------------------------------------------
170 extern wxList wxPendingDelete
;
171 extern wxList wxTopLevelWindows
;
172 extern bool g_blockEventsOnDrag
;
173 extern bool g_blockEventsOnScroll
;
174 static bool g_capturing
= FALSE
;
175 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
177 // hack: we need something to pass to gtk_menu_popup, so we store the time of
178 // the last click here
179 static guint32 gs_timeLastClick
= 0;
181 //-----------------------------------------------------------------------------
182 // "expose_event" (of m_wxwindow, not of m_widget)
183 //-----------------------------------------------------------------------------
185 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
187 if (!win
->HasVMT()) return;
189 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
191 gdk_event
->area
.width
,
192 gdk_event
->area
.height
);
194 if (gdk_event
->count
> 0) return;
197 printf( "OnExpose from " );
198 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
199 printf( win->GetClassInfo()->GetClassName() );
203 wxPaintEvent
event( win
->GetId() );
204 event
.SetEventObject( win
);
205 win
->GetEventHandler()->ProcessEvent( event
);
207 win
->m_updateRegion
.Clear();
210 //-----------------------------------------------------------------------------
211 // "draw" (of m_wxwindow, not of m_widget)
212 //-----------------------------------------------------------------------------
214 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
216 if (!win
->HasVMT()) return;
218 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
220 wxPaintEvent
event( win
->GetId() );
221 event
.SetEventObject( win
);
222 win
->GetEventHandler()->ProcessEvent( event
);
224 win
->m_updateRegion
.Clear();
227 //-----------------------------------------------------------------------------
228 // "key_press_event" from any window
229 //-----------------------------------------------------------------------------
231 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
233 if (!win
->HasVMT()) return FALSE
;
234 if (g_blockEventsOnDrag
) return FALSE
;
237 printf( "OnKeyPress from " );
238 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
239 printf( win->GetClassInfo()->GetClassName() );
244 switch (gdk_event
->keyval
)
246 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
247 case GDK_ISO_Left_Tab
:
249 case GDK_Tab
: key_code
= WXK_TAB
; break;
250 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
251 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
252 case GDK_Return
: key_code
= WXK_RETURN
; break;
253 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
254 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
255 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
256 case GDK_Delete
: key_code
= WXK_DELETE
; break;
257 case GDK_Home
: key_code
= WXK_HOME
; break;
258 case GDK_Left
: key_code
= WXK_LEFT
; break;
259 case GDK_Up
: key_code
= WXK_UP
; break;
260 case GDK_Right
: key_code
= WXK_RIGHT
; break;
261 case GDK_Down
: key_code
= WXK_DOWN
; break;
262 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
263 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
264 case GDK_Next
: key_code
= WXK_NEXT
; break;
265 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
266 case GDK_End
: key_code
= WXK_END
; break;
267 case GDK_Begin
: key_code
= WXK_HOME
; break;
268 case GDK_Select
: key_code
= WXK_SELECT
; break;
269 case GDK_Print
: key_code
= WXK_PRINT
; break;
270 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
271 case GDK_Insert
: key_code
= WXK_INSERT
; break;
272 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
273 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
274 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
275 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
276 case GDK_KP_Up
: key_code
= WXK_UP
; break;
277 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
278 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
279 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
280 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
281 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
282 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
283 case GDK_KP_End
: key_code
= WXK_END
; break;
284 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
285 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
286 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
287 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
288 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
289 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
290 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
291 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
292 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
293 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
294 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
295 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
296 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
297 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
298 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
299 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
300 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
301 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
302 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
303 case GDK_F1
: key_code
= WXK_F1
; break;
304 case GDK_F2
: key_code
= WXK_F2
; break;
305 case GDK_F3
: key_code
= WXK_F3
; break;
306 case GDK_F4
: key_code
= WXK_F4
; break;
307 case GDK_F5
: key_code
= WXK_F5
; break;
308 case GDK_F6
: key_code
= WXK_F6
; break;
309 case GDK_F7
: key_code
= WXK_F7
; break;
310 case GDK_F8
: key_code
= WXK_F8
; break;
311 case GDK_F9
: key_code
= WXK_F9
; break;
312 case GDK_F10
: key_code
= WXK_F10
; break;
313 case GDK_F11
: key_code
= WXK_F11
; break;
314 case GDK_F12
: key_code
= WXK_F12
; break;
317 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
318 key_code
= gdk_event
->keyval
;
322 if (!key_code
) return FALSE
;
324 wxKeyEvent
event( wxEVT_KEY_DOWN
);
325 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
326 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
327 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
328 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
329 event
.m_keyCode
= key_code
;
332 event
.SetEventObject( win
);
334 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
338 wxWindow
*ancestor
= win
;
341 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
344 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
345 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
348 ancestor
= ancestor
->GetParent();
352 // win is a control: tab can be propagated up
354 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
355 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
357 wxNavigationKeyEvent new_event
;
358 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
359 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
360 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
361 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
362 new_event
.SetCurrentFocus( win
);
363 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
367 (gdk_event
->keyval
== GDK_Escape
) )
369 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
370 new_event
.SetEventObject( win
);
371 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
375 Damn, I forgot why this didn't work, but it didn't work.
377 // win is a panel: up can be propagated to the panel
378 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
379 (gdk_event->keyval == GDK_Up))
381 win->m_parent->SetFocus();
385 // win is a panel: left/right can be propagated to the panel
386 if ((!ret) && (win->m_wxwindow) &&
387 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
388 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
390 wxNavigationKeyEvent new_event;
391 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
392 new_event.SetCurrentFocus( win );
393 ret = win->GetEventHandler()->ProcessEvent( new_event );
399 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
405 //-----------------------------------------------------------------------------
406 // "key_release_event" from any window
407 //-----------------------------------------------------------------------------
409 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
411 if (!win
->HasVMT()) return FALSE
;
412 if (g_blockEventsOnDrag
) return FALSE
;
415 printf( "OnKeyRelease from " );
416 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
417 printf( win->GetClassInfo()->GetClassName() );
422 switch (gdk_event
->keyval
)
424 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
425 case GDK_ISO_Left_Tab
:
427 case GDK_Tab
: key_code
= WXK_TAB
; break;
428 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
429 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
430 case GDK_Return
: key_code
= WXK_RETURN
; break;
431 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
432 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
433 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
434 case GDK_Delete
: key_code
= WXK_DELETE
; break;
435 case GDK_Home
: key_code
= WXK_HOME
; break;
436 case GDK_Left
: key_code
= WXK_LEFT
; break;
437 case GDK_Up
: key_code
= WXK_UP
; break;
438 case GDK_Right
: key_code
= WXK_RIGHT
; break;
439 case GDK_Down
: key_code
= WXK_DOWN
; break;
440 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
441 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
442 case GDK_Next
: key_code
= WXK_NEXT
; break;
443 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
444 case GDK_End
: key_code
= WXK_END
; break;
445 case GDK_Begin
: key_code
= WXK_HOME
; break;
446 case GDK_Select
: key_code
= WXK_SELECT
; break;
447 case GDK_Print
: key_code
= WXK_PRINT
; break;
448 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
449 case GDK_Insert
: key_code
= WXK_INSERT
; break;
450 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
451 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
452 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
453 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
454 case GDK_KP_Up
: key_code
= WXK_UP
; break;
455 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
456 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
457 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
458 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
459 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
460 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
461 case GDK_KP_End
: key_code
= WXK_END
; break;
462 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
463 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
464 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
465 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
466 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
467 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
468 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
469 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
470 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
471 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
472 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
473 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
474 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
475 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
476 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
477 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
478 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
479 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
480 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
481 case GDK_F1
: key_code
= WXK_F1
; break;
482 case GDK_F2
: key_code
= WXK_F2
; break;
483 case GDK_F3
: key_code
= WXK_F3
; break;
484 case GDK_F4
: key_code
= WXK_F4
; break;
485 case GDK_F5
: key_code
= WXK_F5
; break;
486 case GDK_F6
: key_code
= WXK_F6
; break;
487 case GDK_F7
: key_code
= WXK_F7
; break;
488 case GDK_F8
: key_code
= WXK_F8
; break;
489 case GDK_F9
: key_code
= WXK_F9
; break;
490 case GDK_F10
: key_code
= WXK_F10
; break;
491 case GDK_F11
: key_code
= WXK_F11
; break;
492 case GDK_F12
: key_code
= WXK_F12
; break;
495 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
496 key_code
= gdk_event
->keyval
;
500 if (!key_code
) return FALSE
;
502 wxKeyEvent
event( wxEVT_KEY_UP
);
503 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
504 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
505 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
506 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
507 event
.m_keyCode
= key_code
;
510 event
.SetEventObject( win
);
512 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
516 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
522 //-----------------------------------------------------------------------------
523 // "button_press_event"
524 //-----------------------------------------------------------------------------
526 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
528 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
530 if (g_blockEventsOnDrag
) return TRUE
;
531 if (g_blockEventsOnScroll
) return TRUE
;
535 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
537 gtk_widget_grab_focus (win
->m_wxwindow
);
540 printf( "GrabFocus from " );
541 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
542 printf( win->GetClassInfo()->GetClassName() );
549 if (!win
->HasVMT()) return TRUE
;
552 printf( "OnButtonPress from " );
553 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
554 printf( win->GetClassInfo()->GetClassName() );
558 wxEventType event_type
= wxEVT_LEFT_DOWN
;
560 if (gdk_event
->button
== 1)
562 switch (gdk_event
->type
)
564 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
565 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
569 else if (gdk_event
->button
== 2)
571 switch (gdk_event
->type
)
573 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
574 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
578 else if (gdk_event
->button
== 3)
580 switch (gdk_event
->type
)
582 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
583 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
588 wxMouseEvent
event( event_type
);
589 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
590 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
591 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
592 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
593 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
594 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
595 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
597 event
.m_x
= (long)gdk_event
->x
;
598 event
.m_y
= (long)gdk_event
->y
;
600 // Some control don't have their own X window and thus cannot get
605 wxNode
*node
= win
->GetChildren().First();
608 wxWindow
*child
= (wxWindow
*)node
->Data();
610 if (child
->m_isStaticBox
)
612 // wxStaticBox is transparent in the box itself
615 int xx1
= child
->m_x
;
616 int yy1
= child
->m_y
;
617 int xx2
= child
->m_x
+ child
->m_width
;
618 int yy2
= child
->m_x
+ child
->m_height
;
621 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
623 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
625 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
627 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
630 event
.m_x
-= child
->m_x
;
631 event
.m_y
-= child
->m_y
;
638 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
639 (child
->m_x
<= event
.m_x
) &&
640 (child
->m_y
<= event
.m_y
) &&
641 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
642 (child
->m_y
+child
->m_height
>= event
.m_y
))
645 event
.m_x
-= child
->m_x
;
646 event
.m_y
-= child
->m_y
;
654 wxPoint
pt(win
->GetClientAreaOrigin());
658 event
.SetEventObject( win
);
660 gs_timeLastClick
= gdk_event
->time
;
662 if (win
->GetEventHandler()->ProcessEvent( event
))
663 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
668 //-----------------------------------------------------------------------------
669 // "button_release_event"
670 //-----------------------------------------------------------------------------
672 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
674 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
676 if (g_blockEventsOnDrag
) return TRUE
;
677 if (g_blockEventsOnScroll
) return TRUE
;
679 if (!win
->HasVMT()) return TRUE
;
682 printf( "OnButtonRelease from " );
683 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
684 printf( win->GetClassInfo()->GetClassName() );
688 wxEventType event_type
= wxEVT_NULL
;
690 switch (gdk_event
->button
)
692 case 1: event_type
= wxEVT_LEFT_UP
; break;
693 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
694 case 3: event_type
= wxEVT_RIGHT_UP
; break;
697 wxMouseEvent
event( event_type
);
698 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
699 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
700 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
701 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
702 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
703 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
704 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
705 event
.m_x
= (long)gdk_event
->x
;
706 event
.m_y
= (long)gdk_event
->y
;
708 // Some control don't have their own X window and thus cannot get
713 wxNode
*node
= win
->GetChildren().First();
716 wxWindow
*child
= (wxWindow
*)node
->Data();
718 if (child
->m_isStaticBox
)
720 // wxStaticBox is transparent in the box itself
723 int xx1
= child
->m_x
;
724 int yy1
= child
->m_y
;
725 int xx2
= child
->m_x
+ child
->m_width
;
726 int yy2
= child
->m_x
+ child
->m_height
;
729 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
731 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
733 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
735 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
738 event
.m_x
-= child
->m_x
;
739 event
.m_y
-= child
->m_y
;
746 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
747 (child
->m_x
<= event
.m_x
) &&
748 (child
->m_y
<= event
.m_y
) &&
749 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
750 (child
->m_y
+child
->m_height
>= event
.m_y
))
753 event
.m_x
-= child
->m_x
;
754 event
.m_y
-= child
->m_y
;
762 wxPoint
pt(win
->GetClientAreaOrigin());
766 event
.SetEventObject( win
);
768 if (win
->GetEventHandler()->ProcessEvent( event
))
769 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
774 //-----------------------------------------------------------------------------
775 // "motion_notify_event"
776 //-----------------------------------------------------------------------------
778 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
780 if (gdk_event
->is_hint
)
784 GdkModifierType state
;
785 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
788 gdk_event
->state
= state
;
791 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
793 if (g_blockEventsOnDrag
) return TRUE
;
794 if (g_blockEventsOnScroll
) return TRUE
;
796 if (!win
->HasVMT()) return TRUE
;
799 printf( "OnMotion from " );
800 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
801 printf( win->GetClassInfo()->GetClassName() );
805 wxMouseEvent
event( wxEVT_MOTION
);
806 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
807 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
808 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
809 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
810 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
811 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
812 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
814 event
.m_x
= (long)gdk_event
->x
;
815 event
.m_y
= (long)gdk_event
->y
;
817 // Some control don't have their own X window and thus cannot get
822 wxNode
*node
= win
->GetChildren().First();
825 wxWindow
*child
= (wxWindow
*)node
->Data();
827 if (child
->m_isStaticBox
)
829 // wxStaticBox is transparent in the box itself
832 int xx1
= child
->m_x
;
833 int yy1
= child
->m_y
;
834 int xx2
= child
->m_x
+ child
->m_width
;
835 int yy2
= child
->m_x
+ child
->m_height
;
838 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
840 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
842 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
844 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
847 event
.m_x
-= child
->m_x
;
848 event
.m_y
-= child
->m_y
;
855 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
856 (child
->m_x
<= event
.m_x
) &&
857 (child
->m_y
<= event
.m_y
) &&
858 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
859 (child
->m_y
+child
->m_height
>= event
.m_y
))
862 event
.m_x
-= child
->m_x
;
863 event
.m_y
-= child
->m_y
;
871 wxPoint
pt(win
->GetClientAreaOrigin());
875 event
.SetEventObject( win
);
877 if (win
->GetEventHandler()->ProcessEvent( event
))
878 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
883 //-----------------------------------------------------------------------------
885 //-----------------------------------------------------------------------------
887 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
889 if (g_blockEventsOnDrag
) return TRUE
;
895 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
897 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
899 printf( "SetFocus flag from " );
900 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
901 printf( win->GetClassInfo()->GetClassName() );
907 if (!win
->HasVMT()) return TRUE
;
910 printf( "OnSetFocus from " );
911 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
912 printf( win->GetClassInfo()->GetClassName() );
914 printf( WXSTRINGCAST win->GetLabel() );
918 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
919 event
.SetEventObject( win
);
921 if (win
->GetEventHandler()->ProcessEvent( event
))
922 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
927 //-----------------------------------------------------------------------------
929 //-----------------------------------------------------------------------------
931 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
933 if (g_blockEventsOnDrag
) return TRUE
;
936 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
937 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
940 if (!win
->HasVMT()) return TRUE
;
943 printf( "OnKillFocus from " );
944 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
945 printf( win->GetClassInfo()->GetClassName() );
949 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
950 event
.SetEventObject( win
);
952 if (win
->GetEventHandler()->ProcessEvent( event
))
953 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
958 //-----------------------------------------------------------------------------
959 // "enter_notify_event"
960 //-----------------------------------------------------------------------------
962 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
964 if (g_blockEventsOnDrag
) return TRUE
;
966 if ((widget
->window
) && (win
->m_cursor
))
967 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
969 if (widget
->window
!= gdk_event
->window
) return TRUE
;
971 if (!win
->HasVMT()) return TRUE
;
974 printf( "OnEnter from " );
975 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
976 printf( win->GetClassInfo()->GetClassName() );
980 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
981 event
.SetEventObject( win
);
985 GdkModifierType state
= (GdkModifierType
)0;
987 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
989 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
990 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
991 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
992 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
993 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
994 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
995 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1000 wxPoint
pt(win
->GetClientAreaOrigin());
1004 if (win
->GetEventHandler()->ProcessEvent( event
))
1005 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1010 //-----------------------------------------------------------------------------
1011 // "leave_notify_event"
1012 //-----------------------------------------------------------------------------
1014 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1016 if (g_blockEventsOnDrag
) return TRUE
;
1018 if ((widget
->window
) && (win
->m_cursor
))
1019 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1021 if (widget
->window
!= gdk_event
->window
) return TRUE
;
1023 if (!win
->HasVMT()) return TRUE
;
1026 printf( "OnLeave from " );
1027 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1028 printf( win->GetClassInfo()->GetClassName() );
1032 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1033 event
.SetEventObject( win
);
1037 GdkModifierType state
= (GdkModifierType
)0;
1039 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1041 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1042 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1043 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1044 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1045 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1046 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1047 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1049 event
.m_x
= (long)x
;
1050 event
.m_y
= (long)y
;
1052 wxPoint
pt(win
->GetClientAreaOrigin());
1056 if (win
->GetEventHandler()->ProcessEvent( event
))
1057 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1062 //-----------------------------------------------------------------------------
1063 // "value_changed" from m_vAdjust
1064 //-----------------------------------------------------------------------------
1066 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1068 if (g_blockEventsOnDrag
) return;
1071 printf( "OnVScroll from " );
1072 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1073 printf( win->GetClassInfo()->GetClassName() );
1077 if (!win
->HasVMT()) return;
1079 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1080 if (fabs(diff
) < 0.2) return;
1082 wxEventType command
= wxEVT_NULL
;
1084 float line_step
= win
->m_vAdjust
->step_increment
;
1085 float page_step
= win
->m_vAdjust
->page_increment
;
1087 if (win
->m_isScrolling
)
1089 command
= wxEVT_SCROLL_THUMBTRACK
;
1093 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1094 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1095 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1096 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1097 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1098 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1099 else command
= wxEVT_SCROLL_THUMBTRACK
;
1102 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1104 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1105 event
.SetEventObject( win
);
1106 win
->GetEventHandler()->ProcessEvent( event
);
1109 //-----------------------------------------------------------------------------
1110 // "value_changed" from m_hAdjust
1111 //-----------------------------------------------------------------------------
1113 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1115 if (g_blockEventsOnDrag
) return;
1118 printf( "OnHScroll from " );
1119 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1120 printf( win->GetClassInfo()->GetClassName() );
1124 if (!win
->HasVMT()) return;
1126 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1127 if (fabs(diff
) < 0.2) return;
1129 wxEventType command
= wxEVT_NULL
;
1131 float line_step
= win
->m_hAdjust
->step_increment
;
1132 float page_step
= win
->m_hAdjust
->page_increment
;
1134 if (win
->m_isScrolling
)
1136 command
= wxEVT_SCROLL_THUMBTRACK
;
1140 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1141 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1142 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1143 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1144 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1145 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1146 else command
= wxEVT_SCROLL_THUMBTRACK
;
1149 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1151 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1152 event
.SetEventObject( win
);
1153 win
->GetEventHandler()->ProcessEvent( event
);
1156 //-----------------------------------------------------------------------------
1157 // "changed" from m_vAdjust
1158 //-----------------------------------------------------------------------------
1160 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1162 if (g_blockEventsOnDrag
) return;
1165 printf( "OnVScroll change from " );
1166 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1167 printf( win->GetClassInfo()->GetClassName() );
1171 if (!win
->HasVMT()) return;
1173 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1174 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1176 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1177 event
.SetEventObject( win
);
1178 win
->GetEventHandler()->ProcessEvent( event
);
1181 //-----------------------------------------------------------------------------
1182 // "changed" from m_hAdjust
1183 //-----------------------------------------------------------------------------
1185 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1187 if (g_blockEventsOnDrag
) return;
1190 printf( "OnHScroll change from " );
1191 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1192 printf( win->GetClassInfo()->GetClassName() );
1196 if (!win
->HasVMT()) return;
1198 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1199 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1201 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1202 event
.SetEventObject( win
);
1203 win
->GetEventHandler()->ProcessEvent( event
);
1206 //-----------------------------------------------------------------------------
1207 // "button_press_event" from scrollbar
1208 //-----------------------------------------------------------------------------
1210 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1211 GdkEventButton
*WXUNUSED(gdk_event
),
1214 // don't test here as we can release the mouse while being over
1215 // a different window then the slider
1217 // if (gdk_event->window != widget->slider) return FALSE;
1219 win
->m_isScrolling
= TRUE
;
1220 g_blockEventsOnScroll
= TRUE
;
1225 //-----------------------------------------------------------------------------
1226 // "button_release_event" from scrollbar
1227 //-----------------------------------------------------------------------------
1229 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1230 GdkEventButton
*WXUNUSED(gdk_event
),
1234 // don't test here as we can release the mouse while being over
1235 // a different window then the slider
1237 // if (gdk_event->window != widget->slider) return FALSE;
1239 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1241 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1242 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1244 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1246 win
->m_isScrolling
= FALSE
;
1247 g_blockEventsOnScroll
= FALSE
;
1252 //-----------------------------------------------------------------------------
1253 // InsertChild for wxWindow.
1254 //-----------------------------------------------------------------------------
1256 /* Callback for wxWindow. This very strange beast has to be used because
1257 * C++ has no virtual methods in a constructor. We have to emulate a
1258 * virtual function here as wxNotebook requires a different way to insert
1259 * a child in it. I had opted for creating a wxNotebookPage window class
1260 * which would have made this superfluous (such in the MDI window system),
1261 * but no-one was listening to me... */
1263 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1265 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1266 GTK_WIDGET(child
->m_widget
),
1270 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1274 if (wxIS_KIND_OF(parent
,wxFrame
))
1276 parent
->m_sizeSet
= FALSE
;
1279 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1281 /* we now allow a window to get the focus as long as it
1282 doesn't have any children. */
1283 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1287 //-----------------------------------------------------------------------------
1289 //-----------------------------------------------------------------------------
1291 wxWindow
* wxGetActiveWindow()
1293 return g_focusWindow
;
1296 //-----------------------------------------------------------------------------
1298 //-----------------------------------------------------------------------------
1300 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1302 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1303 EVT_SIZE(wxWindow::OnSize
)
1304 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1305 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1306 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1309 wxWindow::wxWindow()
1311 m_widget
= (GtkWidget
*) NULL
;
1312 m_wxwindow
= (GtkWidget
*) NULL
;
1313 m_parent
= (wxWindow
*) NULL
;
1314 m_children
.DeleteContents( FALSE
);
1327 m_eventHandler
= this;
1328 m_windowValidator
= (wxValidator
*) NULL
;
1332 m_cursor
= (wxCursor
*) NULL
;
1333 m_font
= *wxSWISS_FONT
;
1335 m_windowName
= "noname";
1337 m_constraints
= (wxLayoutConstraints
*) NULL
;
1338 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1339 m_windowSizer
= (wxSizer
*) NULL
;
1340 m_sizerParent
= (wxWindow
*) NULL
;
1341 m_autoLayout
= FALSE
;
1345 m_needParent
= TRUE
;
1347 m_hasScrolling
= FALSE
;
1348 m_isScrolling
= FALSE
;
1349 m_hAdjust
= (GtkAdjustment
*) NULL
;
1350 m_vAdjust
= (GtkAdjustment
*) NULL
;
1351 m_oldHorizontalPos
= 0.0;
1352 m_oldVerticalPos
= 0.0;
1357 #if wxUSE_DRAG_AND_DROP
1358 m_dropTarget
= (wxDropTarget
*) NULL
;
1361 m_scrollGC
= (GdkGC
*) NULL
;
1362 m_widgetStyle
= (GtkStyle
*) NULL
;
1364 m_insertCallback
= wxInsertChildInWindow
;
1366 m_clientObject
= (wxClientData
*) NULL
;
1367 m_clientData
= NULL
;
1369 m_isStaticBox
= FALSE
;
1370 m_acceptsFocus
= FALSE
;
1373 m_toolTip
= (wxToolTip
*) NULL
;
1374 #endif // wxUSE_TOOLTIPS
1377 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1378 const wxPoint
&pos
, const wxSize
&size
,
1379 long style
, const wxString
&name
)
1381 m_insertCallback
= wxInsertChildInWindow
;
1382 Create( parent
, id
, pos
, size
, style
, name
);
1385 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1386 const wxPoint
&pos
, const wxSize
&size
,
1387 long style
, const wxString
&name
)
1391 m_needParent
= TRUE
;
1393 PreCreation( parent
, id
, pos
, size
, style
, name
);
1395 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1396 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1399 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1402 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1405 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1406 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1409 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1410 scroll_class
->scrollbar_spacing
= 0;
1412 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1414 m_oldHorizontalPos
= 0.0;
1415 m_oldVerticalPos
= 0.0;
1417 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1418 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1420 m_wxwindow
= gtk_myfixed_new();
1423 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1426 #ifdef NEW_GTK_SCROLL_CODE
1427 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1428 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1430 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1431 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1435 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1438 if (m_windowStyle
& wxRAISED_BORDER
)
1440 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1442 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1444 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1448 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1451 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1453 /* we now allow a window to get the focus as long as it
1454 doesn't have any children. */
1455 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1456 m_acceptsFocus
= FALSE
;
1460 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1461 m_acceptsFocus
= TRUE
;
1464 // shut the viewport up
1465 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1466 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1468 // I _really_ don't want scrollbars in the beginning
1469 m_vAdjust
->lower
= 0.0;
1470 m_vAdjust
->upper
= 1.0;
1471 m_vAdjust
->value
= 0.0;
1472 m_vAdjust
->step_increment
= 1.0;
1473 m_vAdjust
->page_increment
= 1.0;
1474 m_vAdjust
->page_size
= 5.0;
1475 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1476 m_hAdjust
->lower
= 0.0;
1477 m_hAdjust
->upper
= 1.0;
1478 m_hAdjust
->value
= 0.0;
1479 m_hAdjust
->step_increment
= 1.0;
1480 m_hAdjust
->page_increment
= 1.0;
1481 m_hAdjust
->page_size
= 5.0;
1482 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1484 // these handlers block mouse events to any window during scrolling
1485 // such as motion events and prevent GTK and wxWindows from fighting
1486 // over where the slider should be
1488 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1489 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1491 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1492 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1494 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1495 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1497 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1498 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1500 // these handers het notified when screen updates are required either when
1501 // scrolling or when the window size (and therefore scrollbar configuration)
1504 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1505 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1506 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1507 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1509 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1510 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1511 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1512 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1514 gtk_widget_show( m_wxwindow
);
1516 if (m_parent
) m_parent
->AddChild( this );
1518 (m_parent
->m_insertCallback
)( m_parent
, this );
1527 wxWindow::~wxWindow()
1529 // Remove potential dangling pointer
1530 if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel
)))
1532 wxPanel
* panel
= (wxPanel
*) GetParent();
1533 if (panel
->GetLastFocus() == this)
1534 panel
->SetLastFocus((wxWindow
*) NULL
);
1539 #if wxUSE_DRAG_AND_DROP
1542 delete m_dropTarget
;
1543 m_dropTarget
= (wxDropTarget
*) NULL
;
1551 m_toolTip
= (wxToolTip
*) NULL
;
1553 #endif // wxUSE_TOOLTIPS
1555 if (m_widget
) Show( FALSE
);
1559 if (m_parent
) m_parent
->RemoveChild( this );
1561 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1563 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1565 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1567 if (m_widget
) gtk_widget_destroy( m_widget
);
1569 if (m_cursor
) delete m_cursor
;
1571 DeleteRelatedConstraints();
1574 /* This removes any dangling pointers to this window
1575 * in other windows' constraintsInvolvedIn lists. */
1576 UnsetConstraints(m_constraints
);
1577 delete m_constraints
;
1578 m_constraints
= (wxLayoutConstraints
*) NULL
;
1583 delete m_windowSizer
;
1584 m_windowSizer
= (wxSizer
*) NULL
;
1586 /* If this is a child of a sizer, remove self from parent */
1587 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1589 /* Just in case the window has been Closed, but
1590 * we're then deleting immediately: don't leave
1591 * dangling pointers. */
1592 wxPendingDelete
.DeleteObject(this);
1594 /* Just in case we've loaded a top-level window via
1595 * wxWindow::LoadNativeDialog but we weren't a dialog
1597 wxTopLevelWindows
.DeleteObject(this);
1599 if (m_windowValidator
) delete m_windowValidator
;
1601 if (m_clientObject
) delete m_clientObject
;
1604 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1605 const wxPoint
&pos
, const wxSize
&size
,
1606 long style
, const wxString
&name
)
1608 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1610 m_widget
= (GtkWidget
*) NULL
;
1611 m_wxwindow
= (GtkWidget
*) NULL
;
1614 m_children
.DeleteContents( FALSE
);
1617 if (m_width
== -1) m_width
= 20;
1619 if (m_height
== -1) m_height
= 20;
1624 if (!m_needParent
) /* some reasonable defaults */
1628 m_x
= (gdk_screen_width () - m_width
) / 2;
1629 if (m_x
< 10) m_x
= 10;
1633 m_y
= (gdk_screen_height () - m_height
) / 2;
1634 if (m_y
< 10) m_y
= 10;
1645 m_eventHandler
= this;
1647 m_windowId
= id
== -1 ? wxNewId() : id
;
1651 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1652 m_font
= *wxSWISS_FONT
;
1653 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1654 m_foregroundColour
= *wxBLACK
;
1655 m_windowStyle
= style
;
1656 m_windowName
= name
;
1658 m_constraints
= (wxLayoutConstraints
*) NULL
;
1659 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1660 m_windowSizer
= (wxSizer
*) NULL
;
1661 m_sizerParent
= (wxWindow
*) NULL
;
1662 m_autoLayout
= FALSE
;
1664 m_hasScrolling
= FALSE
;
1665 m_isScrolling
= FALSE
;
1666 m_hAdjust
= (GtkAdjustment
*) NULL
;
1667 m_vAdjust
= (GtkAdjustment
*) NULL
;
1668 m_oldHorizontalPos
= 0.0;
1669 m_oldVerticalPos
= 0.0;
1674 #if wxUSE_DRAG_AND_DROP
1675 m_dropTarget
= (wxDropTarget
*) NULL
;
1678 m_windowValidator
= (wxValidator
*) NULL
;
1679 m_scrollGC
= (GdkGC
*) NULL
;
1680 m_widgetStyle
= (GtkStyle
*) NULL
;
1682 m_clientObject
= (wxClientData
*)NULL
;
1683 m_clientData
= NULL
;
1685 m_isStaticBox
= FALSE
;
1688 m_toolTip
= (wxToolTip
*) NULL
;
1689 #endif // wxUSE_TOOLTIPS
1692 void wxWindow::PostCreation()
1694 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1698 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1699 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1701 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1702 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1705 ConnectWidget( GetConnectWidget() );
1707 /* we force the creation of wxFrame and wxDialog in the respective code */
1708 if (m_parent
) gtk_widget_realize( m_widget
);
1710 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1712 SetCursor( *wxSTANDARD_CURSOR
);
1717 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1719 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1720 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1722 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1723 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1725 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1726 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1728 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1729 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1731 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1732 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1734 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1735 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1737 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1738 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1740 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1741 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1743 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1744 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1747 bool wxWindow::HasVMT()
1752 bool wxWindow::Close( bool force
)
1754 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1756 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1757 event
.SetEventObject(this);
1758 event
.SetCanVeto(!force
);
1760 /* return FALSE if window wasn't closed because the application vetoed the
1762 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1765 bool wxWindow::Destroy()
1767 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1774 bool wxWindow::DestroyChildren()
1777 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1780 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1783 if (m_children
.Member(child
)) delete node
;
1789 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1791 // are we to set fonts here ?
1794 wxPoint
wxWindow::GetClientAreaOrigin() const
1796 return wxPoint(0,0);
1799 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1801 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1803 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1809 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1811 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1812 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1814 if (m_resizing
) return; /* I don't like recursions */
1817 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1819 /* don't set the size for children of wxNotebook, just take the values. */
1827 int old_width
= m_width
;
1828 int old_height
= m_height
;
1830 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1832 if (x
!= -1) m_x
= x
;
1833 if (y
!= -1) m_y
= y
;
1834 if (width
!= -1) m_width
= width
;
1835 if (height
!= -1) m_height
= height
;
1845 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1847 if (width
== -1) m_width
= 80;
1850 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1852 if (height
== -1) m_height
= 26;
1855 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1856 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1857 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1858 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1860 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1862 /* the default button has a border around it */
1865 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1866 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border
);
1868 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1872 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1873 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1875 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1876 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1882 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1883 event
.SetEventObject( this );
1884 GetEventHandler()->ProcessEvent( event
);
1889 void wxWindow::OnInternalIdle()
1894 void wxWindow::SetSize( int width
, int height
)
1896 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1899 void wxWindow::Move( int x
, int y
)
1901 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1904 void wxWindow::GetSize( int *width
, int *height
) const
1906 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1908 if (width
) (*width
) = m_width
;
1909 if (height
) (*height
) = m_height
;
1912 void wxWindow::SetClientSize( int width
, int height
)
1914 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1918 SetSize( width
, height
);
1925 if (!m_hasScrolling
)
1927 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1929 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1930 (m_windowStyle
& wxSUNKEN_BORDER
))
1932 dw
+= 2 * window_class
->xthickness
;
1933 dh
+= 2 * window_class
->ythickness
;
1938 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1939 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1941 #ifdef NEW_GTK_SCROLL_CODE
1942 GtkWidget
*viewport
= scroll_window
->child
;
1944 GtkWidget
*viewport
= scroll_window
->viewport
;
1947 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1949 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1950 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1952 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1953 (m_windowStyle
& wxSUNKEN_BORDER
))
1955 dw
+= 2 * viewport_class
->xthickness
;
1956 dh
+= 2 * viewport_class
->ythickness
;
1959 if (scroll_window
->vscrollbar_visible
)
1961 dw
+= vscrollbar
->allocation
.width
;
1962 dw
+= scroll_class
->scrollbar_spacing
;
1965 if (scroll_window
->hscrollbar_visible
)
1967 dh
+= hscrollbar
->allocation
.height
;
1968 dw
+= scroll_class
->scrollbar_spacing
;
1972 SetSize( width
+dw
, height
+dh
);
1976 void wxWindow::GetClientSize( int *width
, int *height
) const
1978 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1982 if (width
) (*width
) = m_width
;
1983 if (height
) (*height
) = m_height
;
1990 if (!m_hasScrolling
)
1992 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1994 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1995 (m_windowStyle
& wxSUNKEN_BORDER
))
1997 dw
+= 2 * window_class
->xthickness
;
1998 dh
+= 2 * window_class
->ythickness
;
2003 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2004 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2006 #ifdef NEW_GTK_SCROLL_CODE
2007 GtkWidget
*viewport
= scroll_window
->child
;
2009 GtkWidget
*viewport
= scroll_window
->viewport
;
2012 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2014 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2015 (m_windowStyle
& wxSUNKEN_BORDER
))
2017 dw
+= 2 * viewport_class
->xthickness
;
2018 dh
+= 2 * viewport_class
->ythickness
;
2021 if (scroll_window
->vscrollbar_visible
)
2023 // dw += vscrollbar->allocation.width;
2024 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
2025 dw
+= scroll_class
->scrollbar_spacing
;
2028 if (scroll_window
->hscrollbar_visible
)
2030 // dh += hscrollbar->allocation.height;
2032 dh
+= scroll_class
->scrollbar_spacing
;
2036 if (width
) (*width
) = m_width
- dw
;
2037 if (height
) (*height
) = m_height
- dh
;
2041 void wxWindow::GetPosition( int *x
, int *y
) const
2043 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2049 void wxWindow::ClientToScreen( int *x
, int *y
)
2051 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2053 GdkWindow
*source
= (GdkWindow
*) NULL
;
2055 source
= m_wxwindow
->window
;
2057 source
= m_widget
->window
;
2061 gdk_window_get_origin( source
, &org_x
, &org_y
);
2065 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2067 org_x
+= m_widget
->allocation
.x
;
2068 org_y
+= m_widget
->allocation
.y
;
2072 wxPoint
pt(GetClientAreaOrigin());
2080 void wxWindow::ScreenToClient( int *x
, int *y
)
2082 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2084 GdkWindow
*source
= (GdkWindow
*) NULL
;
2086 source
= m_wxwindow
->window
;
2088 source
= m_widget
->window
;
2092 gdk_window_get_origin( source
, &org_x
, &org_y
);
2096 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2098 org_x
+= m_widget
->allocation
.x
;
2099 org_y
+= m_widget
->allocation
.y
;
2103 wxPoint
pt(GetClientAreaOrigin());
2111 void wxWindow::Centre( int direction
)
2113 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2122 m_parent
->GetSize( &p_w
, &p_h
);
2123 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2124 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2128 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2129 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2135 void wxWindow::Fit()
2137 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2141 wxNode
*node
= m_children
.First();
2144 wxWindow
*win
= (wxWindow
*)node
->Data();
2146 win
->GetPosition(&wx
, &wy
);
2147 win
->GetSize(&ww
, &wh
);
2148 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2149 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2151 node
= node
->Next();
2154 SetClientSize(maxX
+ 7, maxY
+ 14);
2157 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2159 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2167 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2169 // if (GetAutoLayout()) Layout();
2172 bool wxWindow::Show( bool show
)
2174 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2176 if (show
== m_isShown
) return TRUE
;
2179 gtk_widget_show( m_widget
);
2181 gtk_widget_hide( m_widget
);
2188 void wxWindow::Enable( bool enable
)
2190 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2192 m_isEnabled
= enable
;
2194 gtk_widget_set_sensitive( m_widget
, enable
);
2195 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2198 int wxWindow::GetCharHeight() const
2200 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2202 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2204 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2206 return font
->ascent
+ font
->descent
;
2209 int wxWindow::GetCharWidth() const
2211 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2213 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2215 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2217 return gdk_string_width( font
, "H" );
2220 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2221 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2223 wxFont fontToUse
= m_font
;
2224 if (theFont
) fontToUse
= *theFont
;
2226 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2228 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2229 if (x
) (*x
) = gdk_string_width( font
, string
);
2230 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2231 if (descent
) (*descent
) = font
->descent
;
2232 if (externalLeading
) (*externalLeading
) = 0; // ??
2235 void wxWindow::MakeModal( bool modal
)
2239 // Disable all other windows
2240 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2242 wxNode
*node
= wxTopLevelWindows
.First();
2245 wxWindow
*win
= (wxWindow
*)node
->Data();
2246 if (win
!= this) win
->Enable(!modal
);
2248 node
= node
->Next();
2253 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2255 event
.SetEventType( wxEVT_CHAR
);
2257 if (!GetEventHandler()->ProcessEvent( event
))
2263 void wxWindow::SetFocus()
2265 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2267 GtkWidget
*connect_widget
= GetConnectWidget();
2270 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2272 gtk_widget_grab_focus (connect_widget
);
2274 else if (GTK_IS_CONTAINER(connect_widget
))
2276 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2284 wxWindow
*wxWindow::FindFocus()
2286 return g_focusWindow
;
2289 bool wxWindow::AcceptsFocus() const
2291 return IsEnabled() && IsShown() && m_acceptsFocus
;
2294 void wxWindow::AddChild( wxWindow
*child
)
2296 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2297 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2299 m_children
.Append( child
);
2302 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2304 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2306 wxWindow
*oldParent
= GetParent();
2308 if (oldParent
) oldParent
->RemoveChild( this );
2310 gtk_widget_unparent( m_widget
);
2314 newParent
->AddChild( this );
2315 (newParent
->m_insertCallback
)( newParent
, this );
2321 void wxWindow::RemoveChild( wxWindow
*child
)
2323 m_children
.DeleteObject( child
);
2324 child
->m_parent
= (wxWindow
*) NULL
;
2327 void wxWindow::SetReturnCode( int retCode
)
2329 m_retCode
= retCode
;
2332 int wxWindow::GetReturnCode()
2337 void wxWindow::Raise()
2339 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2341 if (m_widget
) gdk_window_raise( m_widget
->window
);
2344 void wxWindow::Lower()
2346 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2348 if (m_widget
) gdk_window_lower( m_widget
->window
);
2351 wxEvtHandler
*wxWindow::GetEventHandler() const
2353 return m_eventHandler
;
2356 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2358 m_eventHandler
= handler
;
2361 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2363 handler
->SetNextHandler(GetEventHandler());
2364 SetEventHandler(handler
);
2367 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2369 if (GetEventHandler())
2371 wxEvtHandler
*handlerA
= GetEventHandler();
2372 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2373 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2374 SetEventHandler(handlerB
);
2378 return (wxEvtHandler
*) NULL
;
2384 return (wxEvtHandler
*) NULL
;
2387 wxValidator
*wxWindow::GetValidator()
2389 return m_windowValidator
;
2392 void wxWindow::SetValidator( const wxValidator
& validator
)
2394 if (m_windowValidator
) delete m_windowValidator
;
2395 m_windowValidator
= validator
.Clone();
2396 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2399 void wxWindow::SetClientObject( wxClientData
*data
)
2401 if (m_clientObject
) delete m_clientObject
;
2402 m_clientObject
= data
;
2405 wxClientData
*wxWindow::GetClientObject()
2407 return m_clientObject
;
2410 void wxWindow::SetClientData( void *data
)
2412 m_clientData
= data
;
2415 void *wxWindow::GetClientData()
2417 return m_clientData
;
2420 bool wxWindow::IsBeingDeleted()
2425 void wxWindow::SetId( wxWindowID id
)
2430 wxWindowID
wxWindow::GetId() const
2435 void wxWindow::SetCursor( const wxCursor
&cursor
)
2437 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2441 if (cursor
== *m_cursor
) return;
2446 *m_cursor
= *wxSTANDARD_CURSOR
;
2449 if ((m_widget
) && (m_widget
->window
))
2450 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2452 if ((m_wxwindow
) && (m_wxwindow
->window
))
2453 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2456 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2461 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2463 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2465 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2469 gdk_window_clear_area( m_wxwindow
->window
,
2471 rect
->width
, rect
->height
);
2475 gdk_window_clear( m_wxwindow
->window
);
2482 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2484 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2488 GdkRectangle gdk_rect
;
2489 gdk_rect
.x
= rect
->x
;
2490 gdk_rect
.y
= rect
->y
;
2491 gdk_rect
.width
= rect
->width
;
2492 gdk_rect
.height
= rect
->height
;
2495 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2497 gtk_widget_draw( m_widget
, &gdk_rect
);
2501 wxRegion
wxWindow::GetUpdateRegion() const
2503 return m_updateRegion
;
2506 bool wxWindow::IsExposed( int x
, int y
) const
2508 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2511 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2513 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2516 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2518 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2521 bool wxWindow::IsExposed( const wxRect
& rect
) const
2523 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2526 void wxWindow::Clear()
2528 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2530 if (m_wxwindow
&& m_wxwindow
->window
)
2532 gdk_window_clear( m_wxwindow
->window
);
2537 void wxWindow::SetToolTip( const wxString
&tip
)
2541 m_toolTip
->SetTip( tip
);
2545 SetToolTip( new wxToolTip( tip
) );
2548 // setting empty tooltip text does not remove the tooltip any more for
2549 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2552 void wxWindow::SetToolTip( wxToolTip
*tip
)
2556 m_toolTip
->SetTip( (char*) NULL
);
2563 m_toolTip
->Apply( this );
2566 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2568 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2570 #endif // wxUSE_TOOLTIPS
2572 wxColour
wxWindow::GetBackgroundColour() const
2574 return m_backgroundColour
;
2577 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2579 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2581 if (m_backgroundColour
== colour
) return;
2583 m_backgroundColour
= colour
;
2584 if (!m_backgroundColour
.Ok()) return;
2586 if (m_wxwindow
&& m_wxwindow
->window
)
2588 /* wxMSW doesn't clear the window here. I don't do that
2589 either to provide compatibility. call Clear() to do
2592 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2593 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2596 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2598 if (sysbg
.Red() == colour
.Red() &&
2599 sysbg
.Green() == colour
.Green() &&
2600 sysbg
.Blue() == colour
.Blue())
2602 m_backgroundColour
= wxNullColour
;
2604 m_backgroundColour
= sysbg
;
2612 wxColour
wxWindow::GetForegroundColour() const
2614 return m_foregroundColour
;
2617 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2619 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2621 if (m_foregroundColour
== colour
) return;
2623 m_foregroundColour
= colour
;
2624 if (!m_foregroundColour
.Ok()) return;
2626 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2627 if (sysbg
.Red() == colour
.Red() &&
2628 sysbg
.Green() == colour
.Green() &&
2629 sysbg
.Blue() == colour
.Blue())
2631 m_backgroundColour
= wxNullColour
;
2633 m_backgroundColour
= sysbg
;
2641 GtkStyle
*wxWindow::GetWidgetStyle()
2643 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2647 gtk_widget_get_style( m_widget
) );
2649 return m_widgetStyle
;
2652 void wxWindow::SetWidgetStyle()
2654 GtkStyle
*style
= GetWidgetStyle();
2656 gdk_font_unref( style
->font
);
2657 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2659 if (m_foregroundColour
.Ok())
2661 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2662 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2663 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2664 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2667 if (m_backgroundColour
.Ok())
2669 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2670 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2671 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2672 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2673 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2674 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2675 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2676 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2677 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2681 void wxWindow::ApplyWidgetStyle()
2685 bool wxWindow::Validate()
2687 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2689 wxNode
*node
= m_children
.First();
2692 wxWindow
*child
= (wxWindow
*)node
->Data();
2693 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2697 node
= node
->Next();
2702 bool wxWindow::TransferDataToWindow()
2704 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2706 wxNode
*node
= m_children
.First();
2709 wxWindow
*child
= (wxWindow
*)node
->Data();
2710 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2711 !child
->GetValidator()->TransferToWindow() )
2713 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2716 node
= node
->Next();
2721 bool wxWindow::TransferDataFromWindow()
2723 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2725 wxNode
*node
= m_children
.First();
2728 wxWindow
*child
= (wxWindow
*)node
->Data();
2729 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2733 node
= node
->Next();
2738 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2740 m_acceleratorTable
= accel
;
2743 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2745 TransferDataToWindow();
2748 void wxWindow::InitDialog()
2750 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2752 wxInitDialogEvent
event(GetId());
2753 event
.SetEventObject( this );
2754 GetEventHandler()->ProcessEvent(event
);
2757 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2759 menu
->SetInvokingWindow( win
);
2760 wxNode
*node
= menu
->m_items
.First();
2763 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2764 if (menuitem
->IsSubMenu())
2766 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2768 node
= node
->Next();
2772 static gint gs_pop_x
= 0;
2773 static gint gs_pop_y
= 0;
2775 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2777 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2782 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2784 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2786 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2788 SetInvokingWindow( menu
, this );
2796 GTK_MENU(menu
->m_menu
),
2797 (GtkWidget
*) NULL
, // parent menu shell
2798 (GtkWidget
*) NULL
, // parent menu item
2799 (GtkMenuPositionFunc
) pop_pos_callback
,
2800 (gpointer
) this, // client data
2801 0, // button used to activate it
2802 0 //gs_timeLastClick // the time of activation
2807 #if wxUSE_DRAG_AND_DROP
2809 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2811 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2813 GtkWidget
*dnd_widget
= GetConnectWidget();
2815 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2817 if (m_dropTarget
) delete m_dropTarget
;
2818 m_dropTarget
= dropTarget
;
2820 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2823 wxDropTarget
*wxWindow::GetDropTarget() const
2825 return m_dropTarget
;
2830 GtkWidget
* wxWindow::GetConnectWidget()
2832 GtkWidget
*connect_widget
= m_widget
;
2833 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2835 return connect_widget
;
2838 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2840 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2841 return (window
== m_widget
->window
);
2844 void wxWindow::SetFont( const wxFont
&font
)
2846 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2848 if (((wxFont
*)&font
)->Ok())
2851 m_font
= *wxSWISS_FONT
;
2853 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2854 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2855 sysbg
.Green() == m_backgroundColour
.Green() &&
2856 sysbg
.Blue() == m_backgroundColour
.Blue())
2858 m_backgroundColour
= wxNullColour
;
2860 m_backgroundColour
= sysbg
;
2868 void wxWindow::SetWindowStyleFlag( long flag
)
2870 m_windowStyle
= flag
;
2873 long wxWindow::GetWindowStyleFlag() const
2875 return m_windowStyle
;
2878 void wxWindow::CaptureMouse()
2880 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2882 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2884 GtkWidget
*connect_widget
= GetConnectWidget();
2885 gtk_grab_add( connect_widget
);
2886 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2888 (GDK_BUTTON_PRESS_MASK
|
2889 GDK_BUTTON_RELEASE_MASK
|
2890 GDK_POINTER_MOTION_MASK
),
2897 void wxWindow::ReleaseMouse()
2899 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2901 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2903 GtkWidget
*connect_widget
= GetConnectWidget();
2904 gtk_grab_remove( connect_widget
);
2905 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2906 g_capturing
= FALSE
;
2909 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2913 wxString
wxWindow::GetTitle() const
2915 return (wxString
&)m_windowName
;
2918 wxString
wxWindow::GetLabel() const
2923 void wxWindow::SetName( const wxString
&name
)
2925 m_windowName
= name
;
2928 wxString
wxWindow::GetName() const
2930 return (wxString
&)m_windowName
;
2933 bool wxWindow::IsShown() const
2938 bool wxWindow::IsRetained()
2943 wxWindow
*wxWindow::FindWindow( long id
)
2945 if (id
== m_windowId
) return this;
2946 wxNode
*node
= m_children
.First();
2949 wxWindow
*child
= (wxWindow
*)node
->Data();
2950 wxWindow
*res
= child
->FindWindow( id
);
2951 if (res
) return res
;
2952 node
= node
->Next();
2954 return (wxWindow
*) NULL
;
2957 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2959 if (name
== m_windowName
) return this;
2960 wxNode
*node
= m_children
.First();
2963 wxWindow
*child
= (wxWindow
*)node
->Data();
2964 wxWindow
*res
= child
->FindWindow( name
);
2965 if (res
) return res
;
2966 node
= node
->Next();
2968 return (wxWindow
*) NULL
;
2971 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2972 int range
, bool refresh
)
2974 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2976 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2978 m_hasScrolling
= TRUE
;
2980 if (orient
== wxHORIZONTAL
)
2982 float fpos
= (float)pos
;
2983 float frange
= (float)range
;
2984 float fthumb
= (float)thumbVisible
;
2985 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2986 if (fpos
< 0.0) fpos
= 0.0;
2988 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2989 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2991 SetScrollPos( orient
, pos
, refresh
);
2995 m_oldHorizontalPos
= fpos
;
2997 m_hAdjust
->lower
= 0.0;
2998 m_hAdjust
->upper
= frange
;
2999 m_hAdjust
->value
= fpos
;
3000 m_hAdjust
->step_increment
= 1.0;
3001 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3002 m_hAdjust
->page_size
= fthumb
;
3006 float fpos
= (float)pos
;
3007 float frange
= (float)range
;
3008 float fthumb
= (float)thumbVisible
;
3009 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3010 if (fpos
< 0.0) fpos
= 0.0;
3012 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3013 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3015 SetScrollPos( orient
, pos
, refresh
);
3019 m_oldVerticalPos
= fpos
;
3021 m_vAdjust
->lower
= 0.0;
3022 m_vAdjust
->upper
= frange
;
3023 m_vAdjust
->value
= fpos
;
3024 m_vAdjust
->step_increment
= 1.0;
3025 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3026 m_vAdjust
->page_size
= fthumb
;
3029 if (m_wxwindow
->window
)
3031 if (orient
== wxHORIZONTAL
)
3032 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3034 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3036 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3040 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3042 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3044 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3046 if (orient
== wxHORIZONTAL
)
3048 float fpos
= (float)pos
;
3049 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3050 if (fpos
< 0.0) fpos
= 0.0;
3051 m_oldHorizontalPos
= fpos
;
3053 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3054 m_hAdjust
->value
= fpos
;
3058 float fpos
= (float)pos
;
3059 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3060 if (fpos
< 0.0) fpos
= 0.0;
3061 m_oldVerticalPos
= fpos
;
3063 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3064 m_vAdjust
->value
= fpos
;
3069 if (m_wxwindow
->window
)
3071 if (orient
== wxHORIZONTAL
)
3072 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3074 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3079 int wxWindow::GetScrollThumb( int orient
) const
3081 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3083 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3085 if (orient
== wxHORIZONTAL
)
3086 return (int)(m_hAdjust
->page_size
+0.5);
3088 return (int)(m_vAdjust
->page_size
+0.5);
3091 int wxWindow::GetScrollPos( int orient
) const
3093 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3095 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3097 if (orient
== wxHORIZONTAL
)
3098 return (int)(m_hAdjust
->value
+0.5);
3100 return (int)(m_vAdjust
->value
+0.5);
3103 int wxWindow::GetScrollRange( int orient
) const
3105 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3107 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3109 if (orient
== wxHORIZONTAL
)
3110 return (int)(m_hAdjust
->upper
+0.5);
3112 return (int)(m_vAdjust
->upper
+0.5);
3115 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3117 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3119 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3123 GetClientSize( &cw
, &ch
);
3125 int w
= cw
- abs(dx
);
3126 int h
= ch
- abs(dy
);
3127 if ((h
< 0) || (w
< 0))
3134 if (dx
< 0) s_x
= -dx
;
3135 if (dy
< 0) s_y
= -dy
;
3138 if (dx
> 0) d_x
= dx
;
3139 if (dy
> 0) d_y
= dy
;
3143 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3144 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3147 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3148 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3151 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3152 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3153 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3154 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3156 Refresh( TRUE
, &rect
);
3159 //-------------------------------------------------------------------------------------
3161 //-------------------------------------------------------------------------------------
3163 wxLayoutConstraints
*wxWindow::GetConstraints() const
3165 return m_constraints
;
3168 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3172 UnsetConstraints(m_constraints
);
3173 delete m_constraints
;
3175 m_constraints
= constraints
;
3178 // Make sure other windows know they're part of a 'meaningful relationship'
3179 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3180 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3181 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3182 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3183 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3184 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3185 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3186 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3187 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3188 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3189 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3190 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3191 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3192 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3193 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3194 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3200 void wxWindow::SetAutoLayout( bool autoLayout
)
3202 m_autoLayout
= autoLayout
;
3205 bool wxWindow::GetAutoLayout() const
3207 return m_autoLayout
;
3210 wxSizer
*wxWindow::GetSizer() const
3212 return m_windowSizer
;
3215 void wxWindow::SetSizerParent( wxWindow
*win
)
3217 m_sizerParent
= win
;
3220 wxWindow
*wxWindow::GetSizerParent() const
3222 return m_sizerParent
;
3225 // This removes any dangling pointers to this window
3226 // in other windows' constraintsInvolvedIn lists.
3227 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3231 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3232 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3233 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3234 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3235 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3236 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3237 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3238 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3239 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3240 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3241 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3242 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3243 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3244 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3245 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3246 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3250 // Back-pointer to other windows we're involved with, so if we delete
3251 // this window, we must delete any constraints we're involved with.
3252 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3254 if (!m_constraintsInvolvedIn
)
3255 m_constraintsInvolvedIn
= new wxList
;
3256 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3257 m_constraintsInvolvedIn
->Append(otherWin
);
3260 // REMOVE back-pointer to other windows we're involved with.
3261 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3263 if (m_constraintsInvolvedIn
)
3264 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3267 // Reset any constraints that mention this window
3268 void wxWindow::DeleteRelatedConstraints()
3270 if (m_constraintsInvolvedIn
)
3272 wxNode
*node
= m_constraintsInvolvedIn
->First();
3275 wxWindow
*win
= (wxWindow
*)node
->Data();
3276 wxNode
*next
= node
->Next();
3277 wxLayoutConstraints
*constr
= win
->GetConstraints();
3279 // Reset any constraints involving this window
3282 constr
->left
.ResetIfWin((wxWindow
*)this);
3283 constr
->top
.ResetIfWin((wxWindow
*)this);
3284 constr
->right
.ResetIfWin((wxWindow
*)this);
3285 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3286 constr
->width
.ResetIfWin((wxWindow
*)this);
3287 constr
->height
.ResetIfWin((wxWindow
*)this);
3288 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3289 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3294 delete m_constraintsInvolvedIn
;
3295 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3299 void wxWindow::SetSizer(wxSizer
*sizer
)
3301 m_windowSizer
= sizer
;
3303 sizer
->SetSizerParent((wxWindow
*)this);
3310 bool wxWindow::Layout()
3312 if (GetConstraints())
3315 GetClientSize(&w
, &h
);
3316 GetConstraints()->width
.SetValue(w
);
3317 GetConstraints()->height
.SetValue(h
);
3320 // If top level (one sizer), evaluate the sizer's constraints.
3324 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3325 GetSizer()->LayoutPhase1(&noChanges
);
3326 GetSizer()->LayoutPhase2(&noChanges
);
3327 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3332 // Otherwise, evaluate child constraints
3333 ResetConstraints(); // Mark all constraints as unevaluated
3334 DoPhase(1); // Just one phase need if no sizers involved
3336 SetConstraintSizes(); // Recursively set the real window sizes
3342 // Do a phase of evaluating constraints:
3343 // the default behaviour. wxSizers may do a similar
3344 // thing, but also impose their own 'constraints'
3345 // and order the evaluation differently.
3346 bool wxWindow::LayoutPhase1(int *noChanges
)
3348 wxLayoutConstraints
*constr
= GetConstraints();
3351 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3357 bool wxWindow::LayoutPhase2(int *noChanges
)
3367 // Do a phase of evaluating child constraints
3368 bool wxWindow::DoPhase(int phase
)
3370 int noIterations
= 0;
3371 int maxIterations
= 500;
3375 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3379 wxNode
*node
= m_children
.First();
3382 wxWindow
*child
= (wxWindow
*)node
->Data();
3383 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3385 wxLayoutConstraints
*constr
= child
->GetConstraints();
3388 if (succeeded
.Member(child
))
3393 int tempNoChanges
= 0;
3394 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3395 noChanges
+= tempNoChanges
;
3398 succeeded
.Append(child
);
3403 node
= node
->Next();
3410 void wxWindow::ResetConstraints()
3412 wxLayoutConstraints
*constr
= GetConstraints();
3415 constr
->left
.SetDone(FALSE
);
3416 constr
->top
.SetDone(FALSE
);
3417 constr
->right
.SetDone(FALSE
);
3418 constr
->bottom
.SetDone(FALSE
);
3419 constr
->width
.SetDone(FALSE
);
3420 constr
->height
.SetDone(FALSE
);
3421 constr
->centreX
.SetDone(FALSE
);
3422 constr
->centreY
.SetDone(FALSE
);
3424 wxNode
*node
= m_children
.First();
3427 wxWindow
*win
= (wxWindow
*)node
->Data();
3428 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3429 win
->ResetConstraints();
3430 node
= node
->Next();
3434 // Need to distinguish between setting the 'fake' size for
3435 // windows and sizers, and setting the real values.
3436 void wxWindow::SetConstraintSizes(bool recurse
)
3438 wxLayoutConstraints
*constr
= GetConstraints();
3439 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3440 constr
->width
.GetDone() && constr
->height
.GetDone())
3442 int x
= constr
->left
.GetValue();
3443 int y
= constr
->top
.GetValue();
3444 int w
= constr
->width
.GetValue();
3445 int h
= constr
->height
.GetValue();
3447 // If we don't want to resize this window, just move it...
3448 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3449 (constr
->height
.GetRelationship() != wxAsIs
))
3451 // Calls Layout() recursively. AAAGH. How can we stop that.
3452 // Simply take Layout() out of non-top level OnSizes.
3453 SizerSetSize(x
, y
, w
, h
);
3462 char *windowClass
= this->GetClassInfo()->GetClassName();
3465 if (GetName() == "")
3466 winName
= "unnamed";
3468 winName
= GetName();
3469 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3470 (const char *)windowClass
,
3471 (const char *)winName
);
3472 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3473 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3474 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3475 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3476 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3481 wxNode
*node
= m_children
.First();
3484 wxWindow
*win
= (wxWindow
*)node
->Data();
3485 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3486 win
->SetConstraintSizes();
3487 node
= node
->Next();
3492 // This assumes that all sizers are 'on' the same
3493 // window, i.e. the parent of this window.
3494 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3496 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3497 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3501 m_sizerParent
->GetPosition(&xp
, &yp
);
3502 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3507 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3511 TransformSizerToActual(&xx
, &yy
);
3512 SetSize(xx
, yy
, w
, h
);
3515 void wxWindow::SizerMove(int x
, int y
)
3519 TransformSizerToActual(&xx
, &yy
);
3523 // Only set the size/position of the constraint (if any)
3524 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3526 wxLayoutConstraints
*constr
= GetConstraints();
3531 constr
->left
.SetValue(x
);
3532 constr
->left
.SetDone(TRUE
);
3536 constr
->top
.SetValue(y
);
3537 constr
->top
.SetDone(TRUE
);
3541 constr
->width
.SetValue(w
);
3542 constr
->width
.SetDone(TRUE
);
3546 constr
->height
.SetValue(h
);
3547 constr
->height
.SetDone(TRUE
);
3552 void wxWindow::MoveConstraint(int x
, int y
)
3554 wxLayoutConstraints
*constr
= GetConstraints();
3559 constr
->left
.SetValue(x
);
3560 constr
->left
.SetDone(TRUE
);
3564 constr
->top
.SetValue(y
);
3565 constr
->top
.SetDone(TRUE
);
3570 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3572 wxLayoutConstraints
*constr
= GetConstraints();
3575 *w
= constr
->width
.GetValue();
3576 *h
= constr
->height
.GetValue();
3582 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3584 wxLayoutConstraints
*constr
= GetConstraints();
3587 *w
= constr
->width
.GetValue();
3588 *h
= constr
->height
.GetValue();
3591 GetClientSize(w
, h
);
3594 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3596 wxLayoutConstraints
*constr
= GetConstraints();
3599 *x
= constr
->left
.GetValue();
3600 *y
= constr
->top
.GetValue();