1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "window.h"
16 #include "wx/window.h"
20 #include "wx/layout.h"
22 #include "wx/dialog.h"
23 #include "wx/msgdlg.h"
25 #if wxUSE_DRAG_AND_DROP
30 #include "wx/tooltip.h"
34 #include "wx/statusbr.h"
36 #include "wx/settings.h"
43 #include "gdk/gdkprivate.h"
44 #include "gdk/gdkkeysyms.h"
45 #include "wx/gtk/win_gtk.h"
47 //-----------------------------------------------------------------------------
48 // documentation on internals
49 //-----------------------------------------------------------------------------
52 I have been asked several times about writing some documentation about
53 the GTK port of wxWindows, especially its internal structures. Obviously,
54 you cannot understand wxGTK without knowing a little about the GTK, but
55 some more information about what the wxWindow, which is the base class
56 for all other window classes, does seems required as well.
58 What does wxWindow do? It contains the common interface for the following
59 jobs of its descendants:
61 1) Define the rudimentary behaviour common to all window classes, such as
62 resizing, intercepting user input (so as to make it possible to use these
63 events for special purposes in a derived class), window names etc.
65 2) Provide the possibility to contain and manage children, if the derived
66 class is allowed to contain children, which holds true for those window
67 classes which do not display a native GTK widget. To name them, these
68 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
69 work classes are a special case and are handled a bit differently from
70 the rest. The same holds true for the wxNotebook class.
72 3) Provide the possibility to draw into a client area of a window. This,
73 too, only holds true for classes that do not display a native GTK widget
76 4) Provide the entire mechanism for scrolling widgets. This actual inter-
77 face for this is usually in wxScrolledWindow, but the GTK implementation
80 5) A multitude of helper or extra methods for special purposes, such as
81 Drag'n'Drop, managing validators etc.
83 Normally one might expect, that one wxWindows window would always correspond
84 to one GTK widget. Under GTK, there is no such allround widget that has all
85 the functionality. Moreover, the GTK defines a client area as a different
86 widget from the actual widget you are handling. Last but not least some
87 special classes (e.g. wxFrame) handle different categories of widgets and
88 still have the possibility to draw something in the client area.
89 It was therefore required to write a special purpose GTK widget, that would
90 represent a client area in the sense of wxWindows capable to do the jobs
91 2), 3) and 4). I have written this class and it resides in win_gtk.c of
94 All windows must have a widget, with which they interact with other under-
95 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
96 thw wxWindow class has a member variable called m_widget which holds a
97 pointer to this widget. When the window class represents a GTK native widget,
98 this is (in most cases) the only GTK widget the class manages. E.g. the
99 wxStatitText class handles only a GtkLabel widget a pointer to which you
100 can find in m_widget (defined in wxWindow)
102 When the class has a client area for drawing into and for containing children
103 it has to handle the client area widget (of the type GtkMyFixed, defined in
104 win_gtk.c), but there could be any number of widgets, handled by a class
105 The common rule for all windows is only, that the widget that interacts with
106 the rest of GTK must be referenced in m_widget and all other widgets must be
107 children of this widget on the GTK level. The top-most widget, which also
108 represents the client area, must be in the m_wxwindow field and must be of
111 As I said, the window classes that display a GTK native widget only have
112 one widget, so in the case of e.g. the wxButton class m_widget holds a
113 pointer to a GtkButton widget. But windows with client areas (for drawing
114 and children) have a m_widget field that is a pointer to a GtkScrolled-
115 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
116 one is (in the GTK sense) a child of the GtkScrolledWindow.
118 If the m_wxwindow field is set, then all input to this widget is inter-
119 cepted and sent to the wxWindows class. If not, all input to the widget
120 that gets pointed to by m_widget gets intercepted and sent to the class.
124 //-----------------------------------------------------------------------------
126 //-----------------------------------------------------------------------------
128 extern wxList wxPendingDelete
;
129 extern bool g_blockEventsOnDrag
;
130 extern bool g_blockEventsOnScroll
;
131 static bool g_capturing
= FALSE
;
132 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
134 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
135 the last click here */
136 static guint32 gs_timeLastClick
= 0;
138 #if (GTK_MINOR_VERSION > 0)
140 //-----------------------------------------------------------------------------
141 // local code (see below)
142 //-----------------------------------------------------------------------------
144 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
146 if (!win
->HasVMT()) return;
151 if (win
->m_hasScrolling
)
153 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
154 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
157 GtkWidget *hscrollbar = scroll_window->hscrollbar;
158 GtkWidget *vscrollbar = scroll_window->vscrollbar;
160 we use this instead: range.slider_width = 11 + 2*2pts edge
163 if (scroll_window
->vscrollbar_visible
)
165 dw
+= 15; /* dw += vscrollbar->allocation.width; */
166 dw
+= scroll_class
->scrollbar_spacing
;
169 if (scroll_window
->hscrollbar_visible
)
171 dh
+= 15; /* dh += hscrollbar->allocation.height; */
172 dw
+= scroll_class
->scrollbar_spacing
;
178 if (GTK_WIDGET_NO_WINDOW (widget
))
180 dx
+= widget
->allocation
.x
;
181 dy
+= widget
->allocation
.y
;
184 if (win
->m_windowStyle
& wxRAISED_BORDER
)
186 gtk_draw_shadow( widget
->style
,
191 win
->m_width
-dw
, win
->m_height
-dh
);
195 if (win
->m_windowStyle
& wxSUNKEN_BORDER
)
197 gtk_draw_shadow( widget
->style
,
202 win
->m_width
-dw
, win
->m_height
-dh
);
207 //-----------------------------------------------------------------------------
208 // "expose_event" of m_widget
209 //-----------------------------------------------------------------------------
211 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
213 if (gdk_event
->count
> 0) return;
214 draw_frame( widget
, win
);
217 //-----------------------------------------------------------------------------
218 // "draw" of m_wxwindow
219 //-----------------------------------------------------------------------------
221 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
223 draw_frame( widget
, win
);
228 //-----------------------------------------------------------------------------
229 // "expose_event" of m_wxwindow
230 //-----------------------------------------------------------------------------
232 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
234 if (!win
->HasVMT()) return;
236 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
238 gdk_event
->area
.width
,
239 gdk_event
->area
.height
);
241 if (gdk_event
->count
> 0) return;
244 printf( "OnExpose from " );
245 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
246 printf( win->GetClassInfo()->GetClassName() );
250 wxPaintEvent
event( win
->GetId() );
251 event
.SetEventObject( win
);
252 win
->GetEventHandler()->ProcessEvent( event
);
254 win
->m_updateRegion
.Clear();
257 //-----------------------------------------------------------------------------
258 // "draw" of m_wxwindow
259 //-----------------------------------------------------------------------------
261 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
263 if (!win
->HasVMT()) return;
265 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
267 wxPaintEvent
event( win
->GetId() );
268 event
.SetEventObject( win
);
269 win
->GetEventHandler()->ProcessEvent( event
);
271 win
->m_updateRegion
.Clear();
274 //-----------------------------------------------------------------------------
275 // "key_press_event" from any window
276 //-----------------------------------------------------------------------------
278 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
280 if (!win
->HasVMT()) return FALSE
;
281 if (g_blockEventsOnDrag
) return FALSE
;
284 printf( "OnKeyPress from " );
285 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
286 printf( win->GetClassInfo()->GetClassName() );
291 switch (gdk_event
->keyval
)
293 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
294 case GDK_ISO_Left_Tab
:
296 case GDK_Tab
: key_code
= WXK_TAB
; break;
297 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
298 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
299 case GDK_Return
: key_code
= WXK_RETURN
; break;
300 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
301 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
302 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
303 case GDK_Delete
: key_code
= WXK_DELETE
; break;
304 case GDK_Home
: key_code
= WXK_HOME
; break;
305 case GDK_Left
: key_code
= WXK_LEFT
; break;
306 case GDK_Up
: key_code
= WXK_UP
; break;
307 case GDK_Right
: key_code
= WXK_RIGHT
; break;
308 case GDK_Down
: key_code
= WXK_DOWN
; break;
309 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
310 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
311 case GDK_Next
: key_code
= WXK_NEXT
; break;
312 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
313 case GDK_End
: key_code
= WXK_END
; break;
314 case GDK_Begin
: key_code
= WXK_HOME
; break;
315 case GDK_Select
: key_code
= WXK_SELECT
; break;
316 case GDK_Print
: key_code
= WXK_PRINT
; break;
317 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
318 case GDK_Insert
: key_code
= WXK_INSERT
; break;
319 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
320 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
321 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
322 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
323 case GDK_KP_Up
: key_code
= WXK_UP
; break;
324 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
325 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
326 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
327 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
328 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
329 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
330 case GDK_KP_End
: key_code
= WXK_END
; break;
331 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
332 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
333 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
334 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
335 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
336 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
337 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
338 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
339 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
340 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
341 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
342 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
343 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
344 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
345 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
346 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
347 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
348 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
349 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
350 case GDK_F1
: key_code
= WXK_F1
; break;
351 case GDK_F2
: key_code
= WXK_F2
; break;
352 case GDK_F3
: key_code
= WXK_F3
; break;
353 case GDK_F4
: key_code
= WXK_F4
; break;
354 case GDK_F5
: key_code
= WXK_F5
; break;
355 case GDK_F6
: key_code
= WXK_F6
; break;
356 case GDK_F7
: key_code
= WXK_F7
; break;
357 case GDK_F8
: key_code
= WXK_F8
; break;
358 case GDK_F9
: key_code
= WXK_F9
; break;
359 case GDK_F10
: key_code
= WXK_F10
; break;
360 case GDK_F11
: key_code
= WXK_F11
; break;
361 case GDK_F12
: key_code
= WXK_F12
; break;
364 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
365 key_code
= gdk_event
->keyval
;
369 if (!key_code
) return FALSE
;
371 wxKeyEvent
event( wxEVT_KEY_DOWN
);
372 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
373 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
374 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
375 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
376 event
.m_keyCode
= key_code
;
379 event
.SetEventObject( win
);
381 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
385 wxWindow
*ancestor
= win
;
388 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
391 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
392 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
395 ancestor
= ancestor
->GetParent();
399 // win is a control: tab can be propagated up
401 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
402 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
404 wxNavigationKeyEvent new_event
;
405 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
406 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
407 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
408 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
409 new_event
.SetCurrentFocus( win
);
410 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
414 (gdk_event
->keyval
== GDK_Escape
) )
416 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
417 new_event
.SetEventObject( win
);
418 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
422 Damn, I forgot why this didn't work, but it didn't work.
424 // win is a panel: up can be propagated to the panel
425 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
426 (gdk_event->keyval == GDK_Up))
428 win->m_parent->SetFocus();
432 // win is a panel: left/right can be propagated to the panel
433 if ((!ret) && (win->m_wxwindow) &&
434 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
435 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
437 wxNavigationKeyEvent new_event;
438 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
439 new_event.SetCurrentFocus( win );
440 ret = win->GetEventHandler()->ProcessEvent( new_event );
446 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
453 //-----------------------------------------------------------------------------
454 // "key_release_event" from any window
455 //-----------------------------------------------------------------------------
457 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
459 if (!win
->HasVMT()) return FALSE
;
460 if (g_blockEventsOnDrag
) return FALSE
;
463 printf( "OnKeyRelease from " );
464 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
465 printf( win->GetClassInfo()->GetClassName() );
470 switch (gdk_event
->keyval
)
472 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
473 case GDK_ISO_Left_Tab
:
475 case GDK_Tab
: key_code
= WXK_TAB
; break;
476 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
477 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
478 case GDK_Return
: key_code
= WXK_RETURN
; break;
479 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
480 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
481 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
482 case GDK_Delete
: key_code
= WXK_DELETE
; break;
483 case GDK_Home
: key_code
= WXK_HOME
; break;
484 case GDK_Left
: key_code
= WXK_LEFT
; break;
485 case GDK_Up
: key_code
= WXK_UP
; break;
486 case GDK_Right
: key_code
= WXK_RIGHT
; break;
487 case GDK_Down
: key_code
= WXK_DOWN
; break;
488 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
489 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
490 case GDK_Next
: key_code
= WXK_NEXT
; break;
491 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
492 case GDK_End
: key_code
= WXK_END
; break;
493 case GDK_Begin
: key_code
= WXK_HOME
; break;
494 case GDK_Select
: key_code
= WXK_SELECT
; break;
495 case GDK_Print
: key_code
= WXK_PRINT
; break;
496 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
497 case GDK_Insert
: key_code
= WXK_INSERT
; break;
498 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
499 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
500 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
501 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
502 case GDK_KP_Up
: key_code
= WXK_UP
; break;
503 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
504 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
505 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
506 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
507 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
508 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
509 case GDK_KP_End
: key_code
= WXK_END
; break;
510 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
511 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
512 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
513 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
514 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
515 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
516 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
517 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
518 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
519 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
520 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
521 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
522 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
523 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
524 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
525 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
526 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
527 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
528 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
529 case GDK_F1
: key_code
= WXK_F1
; break;
530 case GDK_F2
: key_code
= WXK_F2
; break;
531 case GDK_F3
: key_code
= WXK_F3
; break;
532 case GDK_F4
: key_code
= WXK_F4
; break;
533 case GDK_F5
: key_code
= WXK_F5
; break;
534 case GDK_F6
: key_code
= WXK_F6
; break;
535 case GDK_F7
: key_code
= WXK_F7
; break;
536 case GDK_F8
: key_code
= WXK_F8
; break;
537 case GDK_F9
: key_code
= WXK_F9
; break;
538 case GDK_F10
: key_code
= WXK_F10
; break;
539 case GDK_F11
: key_code
= WXK_F11
; break;
540 case GDK_F12
: key_code
= WXK_F12
; break;
543 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
544 key_code
= gdk_event
->keyval
;
548 if (!key_code
) return FALSE
;
550 wxKeyEvent
event( wxEVT_KEY_UP
);
551 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
552 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
553 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
554 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
555 event
.m_keyCode
= key_code
;
558 event
.SetEventObject( win
);
560 if (win
->GetEventHandler()->ProcessEvent( event
))
562 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
569 //-----------------------------------------------------------------------------
570 // "button_press_event"
571 //-----------------------------------------------------------------------------
573 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
575 if (!win
->HasVMT()) return FALSE
;
576 if (g_blockEventsOnDrag
) return TRUE
;
577 if (g_blockEventsOnScroll
) return TRUE
;
579 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
583 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
585 gtk_widget_grab_focus (win
->m_wxwindow
);
588 printf( "GrabFocus from " );
589 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
590 printf( win->GetClassInfo()->GetClassName() );
598 printf( "OnButtonPress from " );
599 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
600 printf( win->GetClassInfo()->GetClassName() );
604 wxEventType event_type
= wxEVT_LEFT_DOWN
;
606 if (gdk_event
->button
== 1)
608 switch (gdk_event
->type
)
610 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
611 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
615 else if (gdk_event
->button
== 2)
617 switch (gdk_event
->type
)
619 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
620 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
624 else if (gdk_event
->button
== 3)
626 switch (gdk_event
->type
)
628 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
629 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
634 wxMouseEvent
event( event_type
);
635 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
636 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
637 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
638 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
639 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
640 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
641 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
643 event
.m_x
= (long)gdk_event
->x
;
644 event
.m_y
= (long)gdk_event
->y
;
646 // Some control don't have their own X window and thus cannot get
651 wxNode
*node
= win
->GetChildren().First();
654 wxWindow
*child
= (wxWindow
*)node
->Data();
656 if (child
->m_isStaticBox
)
658 // wxStaticBox is transparent in the box itself
661 int xx1
= child
->m_x
;
662 int yy1
= child
->m_y
;
663 int xx2
= child
->m_x
+ child
->m_width
;
664 int yy2
= child
->m_x
+ child
->m_height
;
667 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
669 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
671 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
673 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
676 event
.m_x
-= child
->m_x
;
677 event
.m_y
-= child
->m_y
;
684 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
685 (child
->m_x
<= event
.m_x
) &&
686 (child
->m_y
<= event
.m_y
) &&
687 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
688 (child
->m_y
+child
->m_height
>= event
.m_y
))
691 event
.m_x
-= child
->m_x
;
692 event
.m_y
-= child
->m_y
;
700 event
.SetEventObject( win
);
702 gs_timeLastClick
= gdk_event
->time
;
704 if (win
->GetEventHandler()->ProcessEvent( event
))
706 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
713 //-----------------------------------------------------------------------------
714 // "button_release_event"
715 //-----------------------------------------------------------------------------
717 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
719 if (!win
->HasVMT()) return FALSE
;
720 if (g_blockEventsOnDrag
) return FALSE
;
721 if (g_blockEventsOnScroll
) return FALSE
;
723 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
726 printf( "OnButtonRelease from " );
727 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
728 printf( win->GetClassInfo()->GetClassName() );
732 wxEventType event_type
= wxEVT_NULL
;
734 switch (gdk_event
->button
)
736 case 1: event_type
= wxEVT_LEFT_UP
; break;
737 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
738 case 3: event_type
= wxEVT_RIGHT_UP
; break;
741 wxMouseEvent
event( event_type
);
742 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
743 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
744 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
745 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
746 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
747 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
748 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
749 event
.m_x
= (long)gdk_event
->x
;
750 event
.m_y
= (long)gdk_event
->y
;
752 // Some control don't have their own X window and thus cannot get
757 wxNode
*node
= win
->GetChildren().First();
760 wxWindow
*child
= (wxWindow
*)node
->Data();
762 if (child
->m_isStaticBox
)
764 // wxStaticBox is transparent in the box itself
767 int xx1
= child
->m_x
;
768 int yy1
= child
->m_y
;
769 int xx2
= child
->m_x
+ child
->m_width
;
770 int yy2
= child
->m_x
+ child
->m_height
;
773 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
775 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
777 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
779 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
782 event
.m_x
-= child
->m_x
;
783 event
.m_y
-= child
->m_y
;
790 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
791 (child
->m_x
<= event
.m_x
) &&
792 (child
->m_y
<= event
.m_y
) &&
793 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
794 (child
->m_y
+child
->m_height
>= event
.m_y
))
797 event
.m_x
-= child
->m_x
;
798 event
.m_y
-= child
->m_y
;
806 event
.SetEventObject( win
);
808 if (win
->GetEventHandler()->ProcessEvent( event
))
810 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
817 //-----------------------------------------------------------------------------
818 // "motion_notify_event"
819 //-----------------------------------------------------------------------------
821 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
823 if (!win
->HasVMT()) return FALSE
;
824 if (g_blockEventsOnDrag
) return FALSE
;
825 if (g_blockEventsOnScroll
) return FALSE
;
827 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
829 if (gdk_event
->is_hint
)
833 GdkModifierType state
;
834 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
837 gdk_event
->state
= state
;
841 printf( "OnMotion from " );
842 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
843 printf( win->GetClassInfo()->GetClassName() );
847 wxMouseEvent
event( wxEVT_MOTION
);
848 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
849 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
850 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
851 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
852 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
853 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
854 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
856 event
.m_x
= (long)gdk_event
->x
;
857 event
.m_y
= (long)gdk_event
->y
;
859 // Some control don't have their own X window and thus cannot get
864 wxNode
*node
= win
->GetChildren().First();
867 wxWindow
*child
= (wxWindow
*)node
->Data();
869 if (child
->m_isStaticBox
)
871 // wxStaticBox is transparent in the box itself
874 int xx1
= child
->m_x
;
875 int yy1
= child
->m_y
;
876 int xx2
= child
->m_x
+ child
->m_width
;
877 int yy2
= child
->m_x
+ child
->m_height
;
880 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
882 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
884 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
886 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
889 event
.m_x
-= child
->m_x
;
890 event
.m_y
-= child
->m_y
;
897 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
898 (child
->m_x
<= event
.m_x
) &&
899 (child
->m_y
<= event
.m_y
) &&
900 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
901 (child
->m_y
+child
->m_height
>= event
.m_y
))
904 event
.m_x
-= child
->m_x
;
905 event
.m_y
-= child
->m_y
;
913 event
.SetEventObject( win
);
915 if (win
->GetEventHandler()->ProcessEvent( event
))
917 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
924 //-----------------------------------------------------------------------------
926 //-----------------------------------------------------------------------------
928 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
930 if (!win
->HasVMT()) return FALSE
;
931 if (g_blockEventsOnDrag
) return FALSE
;
937 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
939 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
941 printf( "SetFocus flag from " );
942 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
943 printf( win->GetClassInfo()->GetClassName() );
951 printf( "OnSetFocus from " );
952 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
953 printf( win->GetClassInfo()->GetClassName() );
955 printf( WXSTRINGCAST win->GetLabel() );
959 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
960 event
.SetEventObject( win
);
962 if (win
->GetEventHandler()->ProcessEvent( event
))
964 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
971 //-----------------------------------------------------------------------------
973 //-----------------------------------------------------------------------------
975 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
977 if (!win
->HasVMT()) return FALSE
;
978 if (g_blockEventsOnDrag
) return FALSE
;
982 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
983 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
987 printf( "OnKillFocus from " );
988 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
989 printf( win->GetClassInfo()->GetClassName() );
993 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
994 event
.SetEventObject( win
);
996 if (win
->GetEventHandler()->ProcessEvent( event
))
998 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1005 //-----------------------------------------------------------------------------
1006 // "enter_notify_event"
1007 //-----------------------------------------------------------------------------
1009 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1011 if (!win
->HasVMT()) return FALSE
;
1012 if (g_blockEventsOnDrag
) return FALSE
;
1014 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1016 if ((widget
->window
) && (win
->m_cursor
))
1017 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
1020 printf( "OnEnter from " );
1021 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1022 printf( win->GetClassInfo()->GetClassName() );
1026 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1027 event
.SetEventObject( win
);
1031 GdkModifierType state
= (GdkModifierType
)0;
1033 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1035 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1036 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1037 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1038 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1039 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1040 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1041 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1043 event
.m_x
= (long)x
;
1044 event
.m_y
= (long)y
;
1046 if (win
->GetEventHandler()->ProcessEvent( event
))
1048 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1055 //-----------------------------------------------------------------------------
1056 // "leave_notify_event"
1057 //-----------------------------------------------------------------------------
1059 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1061 if (!win
->HasVMT()) return FALSE
;
1062 if (g_blockEventsOnDrag
) return FALSE
;
1064 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1066 if ((widget
->window
) && (win
->m_cursor
))
1067 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1070 printf( "OnLeave from " );
1071 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1072 printf( win->GetClassInfo()->GetClassName() );
1076 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1077 event
.SetEventObject( win
);
1081 GdkModifierType state
= (GdkModifierType
)0;
1083 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1085 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1086 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1087 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1088 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1089 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1090 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1091 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1093 event
.m_x
= (long)x
;
1094 event
.m_y
= (long)y
;
1096 if (win
->GetEventHandler()->ProcessEvent( event
))
1098 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1105 //-----------------------------------------------------------------------------
1106 // "value_changed" from m_vAdjust
1107 //-----------------------------------------------------------------------------
1109 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1111 if (g_blockEventsOnDrag
) return;
1114 printf( "OnVScroll from " );
1115 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1116 printf( win->GetClassInfo()->GetClassName() );
1120 if (!win
->HasVMT()) return;
1122 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1123 if (fabs(diff
) < 0.2) return;
1124 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1126 wxEventType command
= wxEVT_NULL
;
1128 float line_step
= win
->m_vAdjust
->step_increment
;
1129 float page_step
= win
->m_vAdjust
->page_increment
;
1131 if (win
->m_isScrolling
)
1133 command
= wxEVT_SCROLL_THUMBTRACK
;
1137 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1138 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1139 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1140 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1141 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1142 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1143 else command
= wxEVT_SCROLL_THUMBTRACK
;
1146 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1148 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1149 event
.SetEventObject( win
);
1150 win
->GetEventHandler()->ProcessEvent( event
);
1153 //-----------------------------------------------------------------------------
1154 // "value_changed" from m_hAdjust
1155 //-----------------------------------------------------------------------------
1157 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1159 if (g_blockEventsOnDrag
) return;
1162 printf( "OnHScroll from " );
1163 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1164 printf( win->GetClassInfo()->GetClassName() );
1168 if (!win
->HasVMT()) return;
1170 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1171 if (fabs(diff
) < 0.2) return;
1172 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1174 wxEventType command
= wxEVT_NULL
;
1176 float line_step
= win
->m_hAdjust
->step_increment
;
1177 float page_step
= win
->m_hAdjust
->page_increment
;
1179 if (win
->m_isScrolling
)
1181 command
= wxEVT_SCROLL_THUMBTRACK
;
1185 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1186 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1187 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1188 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1189 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1190 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1191 else command
= wxEVT_SCROLL_THUMBTRACK
;
1194 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1196 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1197 event
.SetEventObject( win
);
1198 win
->GetEventHandler()->ProcessEvent( event
);
1201 //-----------------------------------------------------------------------------
1202 // "changed" from m_vAdjust
1203 //-----------------------------------------------------------------------------
1205 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1207 if (g_blockEventsOnDrag
) return;
1210 printf( "OnVScroll change from " );
1211 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1212 printf( win->GetClassInfo()->GetClassName() );
1216 if (!win
->HasVMT()) return;
1218 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1219 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1221 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1222 event
.SetEventObject( win
);
1223 win
->GetEventHandler()->ProcessEvent( event
);
1226 //-----------------------------------------------------------------------------
1227 // "changed" from m_hAdjust
1228 //-----------------------------------------------------------------------------
1230 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1232 if (g_blockEventsOnDrag
) return;
1235 printf( "OnHScroll change from " );
1236 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1237 printf( win->GetClassInfo()->GetClassName() );
1241 if (!win
->HasVMT()) return;
1243 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1244 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1246 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1247 event
.SetEventObject( win
);
1248 win
->GetEventHandler()->ProcessEvent( event
);
1251 //-----------------------------------------------------------------------------
1252 // "button_press_event" from scrollbar
1253 //-----------------------------------------------------------------------------
1255 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1256 GdkEventButton
*WXUNUSED(gdk_event
),
1259 // don't test here as we can release the mouse while being over
1260 // a different window then the slider
1262 // if (gdk_event->window != widget->slider) return FALSE;
1264 win
->m_isScrolling
= TRUE
;
1265 g_blockEventsOnScroll
= TRUE
;
1270 //-----------------------------------------------------------------------------
1271 // "button_release_event" from scrollbar
1272 //-----------------------------------------------------------------------------
1274 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1275 GdkEventButton
*WXUNUSED(gdk_event
),
1279 // don't test here as we can release the mouse while being over
1280 // a different window then the slider
1282 // if (gdk_event->window != widget->slider) return FALSE;
1284 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1286 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1287 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1289 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1291 win
->m_isScrolling
= FALSE
;
1292 g_blockEventsOnScroll
= FALSE
;
1297 //-----------------------------------------------------------------------------
1298 // InsertChild for wxWindow.
1299 //-----------------------------------------------------------------------------
1301 /* Callback for wxWindow. This very strange beast has to be used because
1302 * C++ has no virtual methods in a constructor. We have to emulate a
1303 * virtual function here as wxNotebook requires a different way to insert
1304 * a child in it. I had opted for creating a wxNotebookPage window class
1305 * which would have made this superfluous (such in the MDI window system),
1306 * but no-one was listening to me... */
1308 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1310 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1311 GTK_WIDGET(child
->m_widget
),
1315 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1319 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1321 /* we now allow a window to get the focus as long as it
1322 doesn't have any children. */
1323 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1327 //-----------------------------------------------------------------------------
1329 //-----------------------------------------------------------------------------
1331 wxWindow
* wxGetActiveWindow()
1333 return g_focusWindow
;
1336 //-----------------------------------------------------------------------------
1338 //-----------------------------------------------------------------------------
1340 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1342 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1343 EVT_SIZE(wxWindow::OnSize
)
1344 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1345 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1346 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1349 void wxWindow::Init()
1353 m_widget
= (GtkWidget
*) NULL
;
1354 m_wxwindow
= (GtkWidget
*) NULL
;
1355 m_parent
= (wxWindow
*) NULL
;
1356 m_children
.DeleteContents( FALSE
);
1369 m_eventHandler
= this;
1370 m_windowValidator
= (wxValidator
*) NULL
;
1374 m_cursor
= (wxCursor
*) NULL
;
1375 m_font
= *wxSWISS_FONT
;
1377 m_windowName
= "noname";
1379 m_constraints
= (wxLayoutConstraints
*) NULL
;
1380 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1381 m_windowSizer
= (wxSizer
*) NULL
;
1382 m_sizerParent
= (wxWindow
*) NULL
;
1383 m_autoLayout
= FALSE
;
1387 m_needParent
= TRUE
;
1389 m_hasScrolling
= FALSE
;
1390 m_isScrolling
= FALSE
;
1391 m_hAdjust
= (GtkAdjustment
*) NULL
;
1392 m_vAdjust
= (GtkAdjustment
*) NULL
;
1393 m_oldHorizontalPos
= 0.0;
1394 m_oldVerticalPos
= 0.0;
1399 #if wxUSE_DRAG_AND_DROP
1400 m_dropTarget
= (wxDropTarget
*) NULL
;
1403 m_scrollGC
= (GdkGC
*) NULL
;
1404 m_widgetStyle
= (GtkStyle
*) NULL
;
1406 m_insertCallback
= wxInsertChildInWindow
;
1408 m_clientObject
= (wxClientData
*) NULL
;
1409 m_clientData
= NULL
;
1411 m_isStaticBox
= FALSE
;
1412 m_acceptsFocus
= FALSE
;
1415 m_toolTip
= (wxToolTip
*) NULL
;
1416 #endif // wxUSE_TOOLTIPS
1419 wxWindow::wxWindow()
1424 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1425 const wxPoint
&pos
, const wxSize
&size
,
1426 long style
, const wxString
&name
)
1430 Create( parent
, id
, pos
, size
, style
, name
);
1433 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1434 const wxPoint
&pos
, const wxSize
&size
,
1435 long style
, const wxString
&name
)
1437 wxASSERT_MSG( m_isWindow
, "Init() must have been called before!" );
1439 PreCreation( parent
, id
, pos
, size
, style
, name
);
1441 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1442 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1444 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1446 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1447 scroll_class
->scrollbar_spacing
= 0;
1449 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1451 m_oldHorizontalPos
= 0.0;
1452 m_oldVerticalPos
= 0.0;
1454 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1455 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1457 m_wxwindow
= gtk_myfixed_new();
1459 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1461 #if (GTK_MINOR_VERSION > 0)
1462 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1464 if (m_windowStyle
& wxRAISED_BORDER
)
1466 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1468 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1470 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1474 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1477 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1479 if (m_windowStyle
& wxRAISED_BORDER
)
1481 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1483 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1485 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1489 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1493 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1495 /* we now allow a window to get the focus as long as it
1496 doesn't have any children. */
1497 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1498 m_acceptsFocus
= FALSE
;
1502 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1503 m_acceptsFocus
= TRUE
;
1506 #if (GTK_MINOR_VERSION == 0)
1507 // shut the viewport up
1508 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1509 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1512 // I _really_ don't want scrollbars in the beginning
1513 m_vAdjust
->lower
= 0.0;
1514 m_vAdjust
->upper
= 1.0;
1515 m_vAdjust
->value
= 0.0;
1516 m_vAdjust
->step_increment
= 1.0;
1517 m_vAdjust
->page_increment
= 1.0;
1518 m_vAdjust
->page_size
= 5.0;
1519 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1520 m_hAdjust
->lower
= 0.0;
1521 m_hAdjust
->upper
= 1.0;
1522 m_hAdjust
->value
= 0.0;
1523 m_hAdjust
->step_increment
= 1.0;
1524 m_hAdjust
->page_increment
= 1.0;
1525 m_hAdjust
->page_size
= 5.0;
1526 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1528 // these handlers block mouse events to any window during scrolling
1529 // such as motion events and prevent GTK and wxWindows from fighting
1530 // over where the slider should be
1532 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1533 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1535 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1536 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1538 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1539 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1541 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1542 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1544 // these handlers get notified when screen updates are required either when
1545 // scrolling or when the window size (and therefore scrollbar configuration)
1548 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1549 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1550 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1551 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1553 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1554 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1555 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1556 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1558 gtk_widget_show( m_wxwindow
);
1560 if (m_parent
) m_parent
->AddChild( this );
1562 (m_parent
->m_insertCallback
)( m_parent
, this );
1571 wxWindow::~wxWindow()
1575 #if wxUSE_DRAG_AND_DROP
1578 delete m_dropTarget
;
1579 m_dropTarget
= (wxDropTarget
*) NULL
;
1587 m_toolTip
= (wxToolTip
*) NULL
;
1589 #endif // wxUSE_TOOLTIPS
1591 if (m_widget
) Show( FALSE
);
1595 if (m_parent
) m_parent
->RemoveChild( this );
1597 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1599 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1601 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1603 if (m_widget
) gtk_widget_destroy( m_widget
);
1605 if (m_cursor
) delete m_cursor
;
1607 DeleteRelatedConstraints();
1610 /* This removes any dangling pointers to this window
1611 * in other windows' constraintsInvolvedIn lists. */
1612 UnsetConstraints(m_constraints
);
1613 delete m_constraints
;
1614 m_constraints
= (wxLayoutConstraints
*) NULL
;
1619 delete m_windowSizer
;
1620 m_windowSizer
= (wxSizer
*) NULL
;
1622 /* If this is a child of a sizer, remove self from parent */
1623 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1625 /* Just in case the window has been Closed, but
1626 * we're then deleting immediately: don't leave
1627 * dangling pointers. */
1628 wxPendingDelete
.DeleteObject(this);
1630 /* Just in case we've loaded a top-level window via
1631 * wxWindow::LoadNativeDialog but we weren't a dialog
1633 wxTopLevelWindows
.DeleteObject(this);
1635 if (m_windowValidator
) delete m_windowValidator
;
1637 if (m_clientObject
) delete m_clientObject
;
1640 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1641 const wxPoint
&pos
, const wxSize
&size
,
1642 long style
, const wxString
&name
)
1644 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1646 m_widget
= (GtkWidget
*) NULL
;
1647 m_wxwindow
= (GtkWidget
*) NULL
;
1650 m_children
.DeleteContents( FALSE
);
1653 if (m_width
== -1) m_width
= 20;
1655 if (m_height
== -1) m_height
= 20;
1660 if (!m_needParent
) /* some reasonable defaults */
1664 m_x
= (gdk_screen_width () - m_width
) / 2;
1665 if (m_x
< 10) m_x
= 10;
1669 m_y
= (gdk_screen_height () - m_height
) / 2;
1670 if (m_y
< 10) m_y
= 10;
1681 m_eventHandler
= this;
1683 m_windowId
= id
== -1 ? wxNewId() : id
;
1687 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1688 m_font
= *wxSWISS_FONT
;
1689 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1690 m_foregroundColour
= *wxBLACK
;
1691 m_windowStyle
= style
;
1692 m_windowName
= name
;
1694 m_constraints
= (wxLayoutConstraints
*) NULL
;
1695 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1696 m_windowSizer
= (wxSizer
*) NULL
;
1697 m_sizerParent
= (wxWindow
*) NULL
;
1698 m_autoLayout
= FALSE
;
1700 m_hasScrolling
= FALSE
;
1701 m_isScrolling
= FALSE
;
1702 m_hAdjust
= (GtkAdjustment
*) NULL
;
1703 m_vAdjust
= (GtkAdjustment
*) NULL
;
1704 m_oldHorizontalPos
= 0.0;
1705 m_oldVerticalPos
= 0.0;
1710 #if wxUSE_DRAG_AND_DROP
1711 m_dropTarget
= (wxDropTarget
*) NULL
;
1714 m_windowValidator
= (wxValidator
*) NULL
;
1715 m_scrollGC
= (GdkGC
*) NULL
;
1716 m_widgetStyle
= (GtkStyle
*) NULL
;
1718 m_clientObject
= (wxClientData
*)NULL
;
1719 m_clientData
= NULL
;
1721 m_isStaticBox
= FALSE
;
1724 m_toolTip
= (wxToolTip
*) NULL
;
1725 #endif // wxUSE_TOOLTIPS
1728 void wxWindow::PostCreation()
1730 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1734 /* these get reported to wxWindows -> wxPaintEvent */
1735 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1736 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1738 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1739 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1741 #if (GTK_MINOR_VERSION > 0)
1742 /* these are called when the "sunken" or "raised" borders are drawn */
1743 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1744 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1746 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1747 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1751 ConnectWidget( GetConnectWidget() );
1753 /* we force the creation of wxFrame and wxDialog in the respective code */
1754 if (m_parent
) gtk_widget_realize( m_widget
);
1756 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1758 SetCursor( *wxSTANDARD_CURSOR
);
1763 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1765 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1766 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1768 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1769 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1771 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1772 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1774 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1775 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1777 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1778 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1780 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1781 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1783 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1784 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1786 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1787 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1789 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1790 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1793 bool wxWindow::HasVMT()
1798 bool wxWindow::Close( bool force
)
1800 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1802 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1803 event
.SetEventObject(this);
1804 event
.SetCanVeto(!force
);
1806 /* return FALSE if window wasn't closed because the application vetoed the
1808 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1811 bool wxWindow::Destroy()
1813 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1820 bool wxWindow::DestroyChildren()
1823 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1826 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1829 if (m_children
.Member(child
)) delete node
;
1835 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1837 // are we to set fonts here ?
1840 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1842 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1843 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1845 if (m_resizing
) return; /* I don't like recursions */
1848 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1850 /* don't set the size for children of wxNotebook, just take the values. */
1858 int old_width
= m_width
;
1859 int old_height
= m_height
;
1861 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1863 if (x
!= -1) m_x
= x
;
1864 if (y
!= -1) m_y
= y
;
1865 if (width
!= -1) m_width
= width
;
1866 if (height
!= -1) m_height
= height
;
1876 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1878 if (width
== -1) m_width
= 80;
1881 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1883 if (height
== -1) m_height
= 26;
1886 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1887 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1888 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1889 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1891 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1893 /* the default button has a border around it */
1896 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
-border
, m_y
-border
);
1898 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1902 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y
);
1904 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1905 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1911 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1912 event
.SetEventObject( this );
1913 GetEventHandler()->ProcessEvent( event
);
1918 void wxWindow::OnInternalIdle()
1923 void wxWindow::GetSize( int *width
, int *height
) const
1925 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1927 if (width
) (*width
) = m_width
;
1928 if (height
) (*height
) = m_height
;
1931 void wxWindow::DoSetClientSize( int width
, int height
)
1933 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1937 SetSize( width
, height
);
1944 if (!m_hasScrolling
)
1946 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1948 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1949 (m_windowStyle
& wxSUNKEN_BORDER
))
1951 dw
+= 2 * window_class
->xthickness
;
1952 dh
+= 2 * window_class
->ythickness
;
1957 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1958 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1960 #if (GTK_MINOR_VERSION == 0)
1961 GtkWidget
*viewport
= scroll_window
->viewport
;
1962 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1964 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1965 (m_windowStyle
& wxSUNKEN_BORDER
))
1967 dw
+= 2 * viewport_class
->xthickness
;
1968 dh
+= 2 * viewport_class
->ythickness
;
1973 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1974 GtkWidget *vscrollbar = scroll_window->vscrollbar;
1976 we use this instead: range.slider_width = 11 + 2*2pts edge
1979 if (scroll_window
->vscrollbar_visible
)
1981 dw
+= 15; /* dw += vscrollbar->allocation.width; */
1982 dw
+= scroll_class
->scrollbar_spacing
;
1985 if (scroll_window
->hscrollbar_visible
)
1987 dh
+= 15; /* dh += hscrollbar->allocation.height; */
1988 dw
+= scroll_class
->scrollbar_spacing
;
1992 SetSize( width
+dw
, height
+dh
);
1996 void wxWindow::GetClientSize( int *width
, int *height
) const
1998 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2002 if (width
) (*width
) = m_width
;
2003 if (height
) (*height
) = m_height
;
2010 if (!m_hasScrolling
)
2012 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2014 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2015 (m_windowStyle
& wxSUNKEN_BORDER
))
2017 dw
+= 2 * window_class
->xthickness
;
2018 dh
+= 2 * window_class
->ythickness
;
2023 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2024 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2026 #if (GTK_MINOR_VERSION == 0)
2027 GtkWidget
*viewport
= scroll_window
->viewport
;
2028 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2030 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2031 (m_windowStyle
& wxSUNKEN_BORDER
))
2033 dw
+= 2 * viewport_class
->xthickness
;
2034 dh
+= 2 * viewport_class
->ythickness
;
2038 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2039 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2041 we use this instead: range.slider_width = 11 + 2*2pts edge
2044 if (scroll_window
->vscrollbar_visible
)
2046 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2047 dw
+= scroll_class
->scrollbar_spacing
;
2050 if (scroll_window
->hscrollbar_visible
)
2052 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2053 dh
+= scroll_class
->scrollbar_spacing
;
2057 if (width
) (*width
) = m_width
- dw
;
2058 if (height
) (*height
) = m_height
- dh
;
2062 void wxWindow::GetPosition( int *x
, int *y
) const
2064 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2070 void wxWindow::ClientToScreen( int *x
, int *y
)
2072 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2074 GdkWindow
*source
= (GdkWindow
*) NULL
;
2076 source
= m_wxwindow
->window
;
2078 source
= m_widget
->window
;
2082 gdk_window_get_origin( source
, &org_x
, &org_y
);
2086 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2088 org_x
+= m_widget
->allocation
.x
;
2089 org_y
+= m_widget
->allocation
.y
;
2097 void wxWindow::ScreenToClient( int *x
, int *y
)
2099 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2101 GdkWindow
*source
= (GdkWindow
*) NULL
;
2103 source
= m_wxwindow
->window
;
2105 source
= m_widget
->window
;
2109 gdk_window_get_origin( source
, &org_x
, &org_y
);
2113 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2115 org_x
+= m_widget
->allocation
.x
;
2116 org_y
+= m_widget
->allocation
.y
;
2124 void wxWindow::Centre( int direction
)
2126 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2135 m_parent
->GetSize( &p_w
, &p_h
);
2136 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2137 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2141 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2142 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2148 void wxWindow::Fit()
2150 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2154 wxNode
*node
= m_children
.First();
2157 wxWindow
*win
= (wxWindow
*)node
->Data();
2159 win
->GetPosition(&wx
, &wy
);
2160 win
->GetSize(&ww
, &wh
);
2161 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2162 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2164 node
= node
->Next();
2167 SetClientSize(maxX
+ 7, maxY
+ 14);
2170 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2172 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2180 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2182 // if (GetAutoLayout()) Layout();
2185 bool wxWindow::Show( bool show
)
2187 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2189 if (show
== m_isShown
) return TRUE
;
2192 gtk_widget_show( m_widget
);
2194 gtk_widget_hide( m_widget
);
2201 void wxWindow::Enable( bool enable
)
2203 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2205 m_isEnabled
= enable
;
2207 gtk_widget_set_sensitive( m_widget
, enable
);
2208 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2211 int wxWindow::GetCharHeight() const
2213 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2215 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2217 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2219 return font
->ascent
+ font
->descent
;
2222 int wxWindow::GetCharWidth() const
2224 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2226 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2228 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2230 return gdk_string_width( font
, "H" );
2233 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2234 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2236 wxFont fontToUse
= m_font
;
2237 if (theFont
) fontToUse
= *theFont
;
2239 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2241 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2242 if (x
) (*x
) = gdk_string_width( font
, string
);
2243 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2244 if (descent
) (*descent
) = font
->descent
;
2245 if (externalLeading
) (*externalLeading
) = 0; // ??
2248 void wxWindow::MakeModal( bool modal
)
2252 // Disable all other windows
2253 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2255 wxNode
*node
= wxTopLevelWindows
.First();
2258 wxWindow
*win
= (wxWindow
*)node
->Data();
2259 if (win
!= this) win
->Enable(!modal
);
2261 node
= node
->Next();
2266 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2268 event
.SetEventType( wxEVT_CHAR
);
2270 if (!GetEventHandler()->ProcessEvent( event
))
2276 void wxWindow::SetFocus()
2278 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2280 GtkWidget
*connect_widget
= GetConnectWidget();
2283 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2285 gtk_widget_grab_focus (connect_widget
);
2287 else if (GTK_IS_CONTAINER(connect_widget
))
2289 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2297 wxWindow
*wxWindow::FindFocus()
2299 return g_focusWindow
;
2302 bool wxWindow::AcceptsFocus() const
2304 return IsEnabled() && IsShown() && m_acceptsFocus
;
2307 void wxWindow::AddChild( wxWindow
*child
)
2309 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2310 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2312 m_children
.Append( child
);
2315 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2317 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2319 wxWindow
*oldParent
= GetParent();
2321 if (oldParent
) oldParent
->RemoveChild( this );
2323 gtk_widget_unparent( m_widget
);
2327 newParent
->AddChild( this );
2328 (newParent
->m_insertCallback
)( newParent
, this );
2334 void wxWindow::RemoveChild( wxWindow
*child
)
2336 m_children
.DeleteObject( child
);
2337 child
->m_parent
= (wxWindow
*) NULL
;
2340 void wxWindow::SetReturnCode( int retCode
)
2342 m_retCode
= retCode
;
2345 int wxWindow::GetReturnCode()
2350 void wxWindow::Raise()
2352 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2354 if (m_widget
) gdk_window_raise( m_widget
->window
);
2357 void wxWindow::Lower()
2359 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2361 if (m_widget
) gdk_window_lower( m_widget
->window
);
2364 wxEvtHandler
*wxWindow::GetEventHandler() const
2366 return m_eventHandler
;
2369 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2371 m_eventHandler
= handler
;
2374 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2376 handler
->SetNextHandler(GetEventHandler());
2377 SetEventHandler(handler
);
2380 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2382 if (GetEventHandler())
2384 wxEvtHandler
*handlerA
= GetEventHandler();
2385 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2386 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2387 SetEventHandler(handlerB
);
2391 return (wxEvtHandler
*) NULL
;
2397 return (wxEvtHandler
*) NULL
;
2400 wxValidator
*wxWindow::GetValidator()
2402 return m_windowValidator
;
2405 void wxWindow::SetValidator( const wxValidator
& validator
)
2407 if (m_windowValidator
) delete m_windowValidator
;
2408 m_windowValidator
= validator
.Clone();
2409 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2412 void wxWindow::SetClientObject( wxClientData
*data
)
2414 if (m_clientObject
) delete m_clientObject
;
2415 m_clientObject
= data
;
2418 wxClientData
*wxWindow::GetClientObject()
2420 return m_clientObject
;
2423 void wxWindow::SetClientData( void *data
)
2425 m_clientData
= data
;
2428 void *wxWindow::GetClientData()
2430 return m_clientData
;
2433 bool wxWindow::IsBeingDeleted()
2438 void wxWindow::SetId( wxWindowID id
)
2443 wxWindowID
wxWindow::GetId() const
2448 void wxWindow::SetCursor( const wxCursor
&cursor
)
2450 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2454 if (cursor
== *m_cursor
) return;
2459 *m_cursor
= *wxSTANDARD_CURSOR
;
2462 if ((m_widget
) && (m_widget
->window
))
2463 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2465 if ((m_wxwindow
) && (m_wxwindow
->window
))
2466 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2469 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2474 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2476 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2478 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2482 gdk_window_clear_area( m_wxwindow
->window
,
2484 rect
->width
, rect
->height
);
2488 gdk_window_clear( m_wxwindow
->window
);
2495 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2497 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2501 GdkRectangle gdk_rect
;
2502 gdk_rect
.x
= rect
->x
;
2503 gdk_rect
.y
= rect
->y
;
2504 gdk_rect
.width
= rect
->width
;
2505 gdk_rect
.height
= rect
->height
;
2508 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2510 gtk_widget_draw( m_widget
, &gdk_rect
);
2514 wxRegion
wxWindow::GetUpdateRegion() const
2516 return m_updateRegion
;
2519 bool wxWindow::IsExposed( int x
, int y
) const
2521 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2524 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2526 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2529 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2531 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2534 bool wxWindow::IsExposed( const wxRect
& rect
) const
2536 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2539 void wxWindow::Clear()
2541 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2543 if (m_wxwindow
&& m_wxwindow
->window
)
2545 gdk_window_clear( m_wxwindow
->window
);
2550 void wxWindow::SetToolTip( const wxString
&tip
)
2554 m_toolTip
->SetTip( tip
);
2558 SetToolTip( new wxToolTip( tip
) );
2561 // setting empty tooltip text does not remove the tooltip any more for
2562 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2565 void wxWindow::SetToolTip( wxToolTip
*tip
)
2569 m_toolTip
->SetTip( (char*) NULL
);
2576 m_toolTip
->Apply( this );
2579 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2581 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2583 #endif // wxUSE_TOOLTIPS
2585 wxColour
wxWindow::GetBackgroundColour() const
2587 return m_backgroundColour
;
2590 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2592 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2594 if (m_backgroundColour
== colour
) return;
2596 m_backgroundColour
= colour
;
2597 if (!m_backgroundColour
.Ok()) return;
2599 if (m_wxwindow
&& m_wxwindow
->window
)
2601 /* wxMSW doesn't clear the window here. I don't do that
2602 either to provide compatibility. call Clear() to do
2605 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2606 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2609 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2611 if (sysbg
.Red() == colour
.Red() &&
2612 sysbg
.Green() == colour
.Green() &&
2613 sysbg
.Blue() == colour
.Blue())
2615 m_backgroundColour
= wxNullColour
;
2617 m_backgroundColour
= sysbg
;
2625 wxColour
wxWindow::GetForegroundColour() const
2627 return m_foregroundColour
;
2630 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2632 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2634 if (m_foregroundColour
== colour
) return;
2636 m_foregroundColour
= colour
;
2637 if (!m_foregroundColour
.Ok()) return;
2639 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2640 if (sysbg
.Red() == colour
.Red() &&
2641 sysbg
.Green() == colour
.Green() &&
2642 sysbg
.Blue() == colour
.Blue())
2644 m_backgroundColour
= wxNullColour
;
2646 m_backgroundColour
= sysbg
;
2654 GtkStyle
*wxWindow::GetWidgetStyle()
2656 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2660 gtk_widget_get_style( m_widget
) );
2662 return m_widgetStyle
;
2665 void wxWindow::SetWidgetStyle()
2667 GtkStyle
*style
= GetWidgetStyle();
2669 gdk_font_unref( style
->font
);
2670 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2672 if (m_foregroundColour
.Ok())
2674 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2675 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2676 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2677 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2680 if (m_backgroundColour
.Ok())
2682 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2683 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2684 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2685 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2686 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2687 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2688 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2689 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2690 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2694 void wxWindow::ApplyWidgetStyle()
2698 bool wxWindow::Validate()
2700 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2702 wxNode
*node
= m_children
.First();
2705 wxWindow
*child
= (wxWindow
*)node
->Data();
2706 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2710 node
= node
->Next();
2715 bool wxWindow::TransferDataToWindow()
2717 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2719 wxNode
*node
= m_children
.First();
2722 wxWindow
*child
= (wxWindow
*)node
->Data();
2723 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2724 !child
->GetValidator()->TransferToWindow() )
2726 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2729 node
= node
->Next();
2734 bool wxWindow::TransferDataFromWindow()
2736 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2738 wxNode
*node
= m_children
.First();
2741 wxWindow
*child
= (wxWindow
*)node
->Data();
2742 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2746 node
= node
->Next();
2751 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2753 m_acceleratorTable
= accel
;
2756 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2758 TransferDataToWindow();
2761 void wxWindow::InitDialog()
2763 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2765 wxInitDialogEvent
event(GetId());
2766 event
.SetEventObject( this );
2767 GetEventHandler()->ProcessEvent(event
);
2770 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2772 menu
->SetInvokingWindow( win
);
2773 wxNode
*node
= menu
->GetItems().First();
2776 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2777 if (menuitem
->IsSubMenu())
2779 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2781 node
= node
->Next();
2785 static gint gs_pop_x
= 0;
2786 static gint gs_pop_y
= 0;
2788 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2790 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2795 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2797 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2799 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2801 SetInvokingWindow( menu
, this );
2809 GTK_MENU(menu
->m_menu
),
2810 (GtkWidget
*) NULL
, // parent menu shell
2811 (GtkWidget
*) NULL
, // parent menu item
2812 (GtkMenuPositionFunc
) pop_pos_callback
,
2813 (gpointer
) this, // client data
2814 0, // button used to activate it
2815 0 //gs_timeLastClick // the time of activation
2820 #if wxUSE_DRAG_AND_DROP
2822 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2824 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2826 GtkWidget
*dnd_widget
= GetConnectWidget();
2828 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2830 if (m_dropTarget
) delete m_dropTarget
;
2831 m_dropTarget
= dropTarget
;
2833 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2836 wxDropTarget
*wxWindow::GetDropTarget() const
2838 return m_dropTarget
;
2843 GtkWidget
* wxWindow::GetConnectWidget()
2845 GtkWidget
*connect_widget
= m_widget
;
2846 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2848 return connect_widget
;
2851 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2853 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2854 return (window
== m_widget
->window
);
2857 void wxWindow::SetFont( const wxFont
&font
)
2859 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2861 if (m_font
== font
) return;
2863 if (((wxFont
*)&font
)->Ok())
2866 m_font
= *wxSWISS_FONT
;
2868 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2869 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2870 sysbg
.Green() == m_backgroundColour
.Green() &&
2871 sysbg
.Blue() == m_backgroundColour
.Blue())
2873 m_backgroundColour
= wxNullColour
;
2875 m_backgroundColour
= sysbg
;
2883 void wxWindow::SetWindowStyleFlag( long flag
)
2885 m_windowStyle
= flag
;
2888 long wxWindow::GetWindowStyleFlag() const
2890 return m_windowStyle
;
2893 void wxWindow::CaptureMouse()
2895 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2897 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2899 GtkWidget
*connect_widget
= GetConnectWidget();
2900 gtk_grab_add( connect_widget
);
2901 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2903 (GDK_BUTTON_PRESS_MASK
|
2904 GDK_BUTTON_RELEASE_MASK
|
2905 GDK_POINTER_MOTION_MASK
),
2912 void wxWindow::ReleaseMouse()
2914 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2916 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2918 GtkWidget
*connect_widget
= GetConnectWidget();
2919 gtk_grab_remove( connect_widget
);
2920 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2921 g_capturing
= FALSE
;
2924 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2928 wxString
wxWindow::GetTitle() const
2930 return (wxString
&)m_windowName
;
2933 wxString
wxWindow::GetLabel() const
2938 void wxWindow::SetName( const wxString
&name
)
2940 m_windowName
= name
;
2943 wxString
wxWindow::GetName() const
2945 return (wxString
&)m_windowName
;
2948 bool wxWindow::IsShown() const
2953 bool wxWindow::IsRetained()
2958 wxWindow
*wxWindow::FindWindow( long id
)
2960 if (id
== m_windowId
) return this;
2961 wxNode
*node
= m_children
.First();
2964 wxWindow
*child
= (wxWindow
*)node
->Data();
2965 wxWindow
*res
= child
->FindWindow( id
);
2966 if (res
) return res
;
2967 node
= node
->Next();
2969 return (wxWindow
*) NULL
;
2972 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2974 if (name
== m_windowName
) return this;
2975 wxNode
*node
= m_children
.First();
2978 wxWindow
*child
= (wxWindow
*)node
->Data();
2979 wxWindow
*res
= child
->FindWindow( name
);
2980 if (res
) return res
;
2981 node
= node
->Next();
2983 return (wxWindow
*) NULL
;
2986 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2987 int range
, bool refresh
)
2989 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2991 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2993 m_hasScrolling
= TRUE
;
2995 if (orient
== wxHORIZONTAL
)
2997 float fpos
= (float)pos
;
2998 float frange
= (float)range
;
2999 float fthumb
= (float)thumbVisible
;
3000 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3001 if (fpos
< 0.0) fpos
= 0.0;
3003 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3004 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3006 SetScrollPos( orient
, pos
, refresh
);
3010 m_oldHorizontalPos
= fpos
;
3012 m_hAdjust
->lower
= 0.0;
3013 m_hAdjust
->upper
= frange
;
3014 m_hAdjust
->value
= fpos
;
3015 m_hAdjust
->step_increment
= 1.0;
3016 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3017 m_hAdjust
->page_size
= fthumb
;
3021 float fpos
= (float)pos
;
3022 float frange
= (float)range
;
3023 float fthumb
= (float)thumbVisible
;
3024 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3025 if (fpos
< 0.0) fpos
= 0.0;
3027 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3028 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3030 SetScrollPos( orient
, pos
, refresh
);
3034 m_oldVerticalPos
= fpos
;
3036 m_vAdjust
->lower
= 0.0;
3037 m_vAdjust
->upper
= frange
;
3038 m_vAdjust
->value
= fpos
;
3039 m_vAdjust
->step_increment
= 1.0;
3040 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3041 m_vAdjust
->page_size
= fthumb
;
3044 if (m_wxwindow
->window
)
3046 if (orient
== wxHORIZONTAL
)
3047 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3049 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3051 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3055 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3057 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3059 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3061 if (orient
== wxHORIZONTAL
)
3063 float fpos
= (float)pos
;
3064 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3065 if (fpos
< 0.0) fpos
= 0.0;
3066 m_oldHorizontalPos
= fpos
;
3068 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3069 m_hAdjust
->value
= fpos
;
3073 float fpos
= (float)pos
;
3074 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3075 if (fpos
< 0.0) fpos
= 0.0;
3076 m_oldVerticalPos
= fpos
;
3078 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3079 m_vAdjust
->value
= fpos
;
3084 if (m_wxwindow
->window
)
3086 if (orient
== wxHORIZONTAL
)
3087 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3089 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3094 int wxWindow::GetScrollThumb( int orient
) const
3096 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3098 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3100 if (orient
== wxHORIZONTAL
)
3101 return (int)(m_hAdjust
->page_size
+0.5);
3103 return (int)(m_vAdjust
->page_size
+0.5);
3106 int wxWindow::GetScrollPos( int orient
) const
3108 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3110 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3112 if (orient
== wxHORIZONTAL
)
3113 return (int)(m_hAdjust
->value
+0.5);
3115 return (int)(m_vAdjust
->value
+0.5);
3118 int wxWindow::GetScrollRange( int orient
) const
3120 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3122 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3124 if (orient
== wxHORIZONTAL
)
3125 return (int)(m_hAdjust
->upper
+0.5);
3127 return (int)(m_vAdjust
->upper
+0.5);
3130 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3132 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3134 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3136 wxNode
*node
= m_children
.First();
3139 wxWindow
*child
= (wxWindow
*) node
->Data();
3140 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
3141 node
= node
->Next();
3146 GetClientSize( &cw
, &ch
);
3148 int w
= cw
- abs(dx
);
3149 int h
= ch
- abs(dy
);
3150 if ((h
< 0) || (w
< 0))
3157 if (dx
< 0) s_x
= -dx
;
3158 if (dy
< 0) s_y
= -dy
;
3161 if (dx
> 0) d_x
= dx
;
3162 if (dy
> 0) d_y
= dy
;
3166 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3167 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3170 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3171 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3174 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3175 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3176 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3177 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3179 Refresh( TRUE
, &rect
);
3182 //-------------------------------------------------------------------------------------
3184 //-------------------------------------------------------------------------------------
3186 wxLayoutConstraints
*wxWindow::GetConstraints() const
3188 return m_constraints
;
3191 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3195 UnsetConstraints(m_constraints
);
3196 delete m_constraints
;
3198 m_constraints
= constraints
;
3201 // Make sure other windows know they're part of a 'meaningful relationship'
3202 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3203 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3204 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3205 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3206 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3207 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3208 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3209 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3210 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3211 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3212 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3213 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3214 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3215 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3216 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3217 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3223 void wxWindow::SetAutoLayout( bool autoLayout
)
3225 m_autoLayout
= autoLayout
;
3228 bool wxWindow::GetAutoLayout() const
3230 return m_autoLayout
;
3233 wxSizer
*wxWindow::GetSizer() const
3235 return m_windowSizer
;
3238 void wxWindow::SetSizerParent( wxWindow
*win
)
3240 m_sizerParent
= win
;
3243 wxWindow
*wxWindow::GetSizerParent() const
3245 return m_sizerParent
;
3248 // This removes any dangling pointers to this window
3249 // in other windows' constraintsInvolvedIn lists.
3250 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3254 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3255 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3256 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3257 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3258 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3259 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3260 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3261 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3262 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3263 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3264 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3265 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3266 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3267 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3268 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3269 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3273 // Back-pointer to other windows we're involved with, so if we delete
3274 // this window, we must delete any constraints we're involved with.
3275 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3277 if (!m_constraintsInvolvedIn
)
3278 m_constraintsInvolvedIn
= new wxList
;
3279 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3280 m_constraintsInvolvedIn
->Append(otherWin
);
3283 // REMOVE back-pointer to other windows we're involved with.
3284 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3286 if (m_constraintsInvolvedIn
)
3287 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3290 // Reset any constraints that mention this window
3291 void wxWindow::DeleteRelatedConstraints()
3293 if (m_constraintsInvolvedIn
)
3295 wxNode
*node
= m_constraintsInvolvedIn
->First();
3298 wxWindow
*win
= (wxWindow
*)node
->Data();
3299 wxNode
*next
= node
->Next();
3300 wxLayoutConstraints
*constr
= win
->GetConstraints();
3302 // Reset any constraints involving this window
3305 constr
->left
.ResetIfWin((wxWindow
*)this);
3306 constr
->top
.ResetIfWin((wxWindow
*)this);
3307 constr
->right
.ResetIfWin((wxWindow
*)this);
3308 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3309 constr
->width
.ResetIfWin((wxWindow
*)this);
3310 constr
->height
.ResetIfWin((wxWindow
*)this);
3311 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3312 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3317 delete m_constraintsInvolvedIn
;
3318 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3322 void wxWindow::SetSizer(wxSizer
*sizer
)
3324 m_windowSizer
= sizer
;
3326 sizer
->SetSizerParent((wxWindow
*)this);
3333 bool wxWindow::Layout()
3335 if (GetConstraints())
3338 GetClientSize(&w
, &h
);
3339 GetConstraints()->width
.SetValue(w
);
3340 GetConstraints()->height
.SetValue(h
);
3343 // If top level (one sizer), evaluate the sizer's constraints.
3347 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3348 GetSizer()->LayoutPhase1(&noChanges
);
3349 GetSizer()->LayoutPhase2(&noChanges
);
3350 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3355 // Otherwise, evaluate child constraints
3356 ResetConstraints(); // Mark all constraints as unevaluated
3357 DoPhase(1); // Just one phase need if no sizers involved
3359 SetConstraintSizes(); // Recursively set the real window sizes
3365 // Do a phase of evaluating constraints:
3366 // the default behaviour. wxSizers may do a similar
3367 // thing, but also impose their own 'constraints'
3368 // and order the evaluation differently.
3369 bool wxWindow::LayoutPhase1(int *noChanges
)
3371 wxLayoutConstraints
*constr
= GetConstraints();
3374 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3380 bool wxWindow::LayoutPhase2(int *noChanges
)
3390 // Do a phase of evaluating child constraints
3391 bool wxWindow::DoPhase(int phase
)
3393 int noIterations
= 0;
3394 int maxIterations
= 500;
3398 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3402 wxNode
*node
= m_children
.First();
3405 wxWindow
*child
= (wxWindow
*)node
->Data();
3406 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3408 wxLayoutConstraints
*constr
= child
->GetConstraints();
3411 if (succeeded
.Member(child
))
3416 int tempNoChanges
= 0;
3417 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3418 noChanges
+= tempNoChanges
;
3421 succeeded
.Append(child
);
3426 node
= node
->Next();
3433 void wxWindow::ResetConstraints()
3435 wxLayoutConstraints
*constr
= GetConstraints();
3438 constr
->left
.SetDone(FALSE
);
3439 constr
->top
.SetDone(FALSE
);
3440 constr
->right
.SetDone(FALSE
);
3441 constr
->bottom
.SetDone(FALSE
);
3442 constr
->width
.SetDone(FALSE
);
3443 constr
->height
.SetDone(FALSE
);
3444 constr
->centreX
.SetDone(FALSE
);
3445 constr
->centreY
.SetDone(FALSE
);
3447 wxNode
*node
= m_children
.First();
3450 wxWindow
*win
= (wxWindow
*)node
->Data();
3451 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3452 win
->ResetConstraints();
3453 node
= node
->Next();
3457 // Need to distinguish between setting the 'fake' size for
3458 // windows and sizers, and setting the real values.
3459 void wxWindow::SetConstraintSizes(bool recurse
)
3461 wxLayoutConstraints
*constr
= GetConstraints();
3462 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3463 constr
->width
.GetDone() && constr
->height
.GetDone())
3465 int x
= constr
->left
.GetValue();
3466 int y
= constr
->top
.GetValue();
3467 int w
= constr
->width
.GetValue();
3468 int h
= constr
->height
.GetValue();
3470 // If we don't want to resize this window, just move it...
3471 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3472 (constr
->height
.GetRelationship() != wxAsIs
))
3474 // Calls Layout() recursively. AAAGH. How can we stop that.
3475 // Simply take Layout() out of non-top level OnSizes.
3476 SizerSetSize(x
, y
, w
, h
);
3485 char *windowClass
= this->GetClassInfo()->GetClassName();
3488 if (GetName() == "")
3489 winName
= "unnamed";
3491 winName
= GetName();
3492 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3493 (const char *)windowClass
,
3494 (const char *)winName
);
3495 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3496 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3497 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3498 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3499 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3504 wxNode
*node
= m_children
.First();
3507 wxWindow
*win
= (wxWindow
*)node
->Data();
3508 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3509 win
->SetConstraintSizes();
3510 node
= node
->Next();
3515 // This assumes that all sizers are 'on' the same
3516 // window, i.e. the parent of this window.
3517 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3519 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3520 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3524 m_sizerParent
->GetPosition(&xp
, &yp
);
3525 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3530 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3534 TransformSizerToActual(&xx
, &yy
);
3535 SetSize(xx
, yy
, w
, h
);
3538 void wxWindow::SizerMove(int x
, int y
)
3542 TransformSizerToActual(&xx
, &yy
);
3546 // Only set the size/position of the constraint (if any)
3547 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3549 wxLayoutConstraints
*constr
= GetConstraints();
3554 constr
->left
.SetValue(x
);
3555 constr
->left
.SetDone(TRUE
);
3559 constr
->top
.SetValue(y
);
3560 constr
->top
.SetDone(TRUE
);
3564 constr
->width
.SetValue(w
);
3565 constr
->width
.SetDone(TRUE
);
3569 constr
->height
.SetValue(h
);
3570 constr
->height
.SetDone(TRUE
);
3575 void wxWindow::MoveConstraint(int x
, int y
)
3577 wxLayoutConstraints
*constr
= GetConstraints();
3582 constr
->left
.SetValue(x
);
3583 constr
->left
.SetDone(TRUE
);
3587 constr
->top
.SetValue(y
);
3588 constr
->top
.SetDone(TRUE
);
3593 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3595 wxLayoutConstraints
*constr
= GetConstraints();
3598 *w
= constr
->width
.GetValue();
3599 *h
= constr
->height
.GetValue();
3605 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3607 wxLayoutConstraints
*constr
= GetConstraints();
3610 *w
= constr
->width
.GetValue();
3611 *h
= constr
->height
.GetValue();
3614 GetClientSize(w
, h
);
3617 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3619 wxLayoutConstraints
*constr
= GetConstraints();
3622 *x
= constr
->left
.GetValue();
3623 *y
= constr
->top
.GetValue();