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 //-----------------------------------------------------------------------------
140 //-----------------------------------------------------------------------------
144 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
145 GdkEvent
*WXUNUSED(event
),
148 // to enable logging of the focus events replace 0 with 1
150 static bool s_done
= FALSE
;
153 wxLog::AddTraceMask("focus");
157 wxLogTrace(_T("FOCUS NOW AT: %s"), name
);
162 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
168 wxChar
*s
= new wxChar
[tmp
.Length()+1];
172 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
173 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
178 //-----------------------------------------------------------------------------
179 // local code (see below)
180 //-----------------------------------------------------------------------------
182 static void InitAdjustment(GtkAdjustment
*adjust
)
187 adjust
->step_increment
= 1.0;
188 adjust
->page_increment
= 1.0;
189 adjust
->page_size
= 5.0;
190 gtk_signal_emit_by_name( GTK_OBJECT(adjust
), "changed" );
193 #if (GTK_MINOR_VERSION > 0)
195 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
203 if (win
->HasScrolling())
205 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
206 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
209 GtkWidget *hscrollbar = scroll_window->hscrollbar;
210 GtkWidget *vscrollbar = scroll_window->vscrollbar;
212 we use this instead: range.slider_width = 11 + 2*2pts edge
215 if (scroll_window
->vscrollbar_visible
)
217 dw
+= 15; /* dw += vscrollbar->allocation.width; */
218 dw
+= scroll_class
->scrollbar_spacing
;
221 if (scroll_window
->hscrollbar_visible
)
223 dh
+= 15; /* dh += hscrollbar->allocation.height; */
224 dw
+= scroll_class
->scrollbar_spacing
;
230 if (GTK_WIDGET_NO_WINDOW (widget
))
232 dx
+= widget
->allocation
.x
;
233 dy
+= widget
->allocation
.y
;
236 if (win
->HasFlag(wxRAISED_BORDER
))
238 gtk_draw_shadow( widget
->style
,
243 win
->GetWidth()-dw
, win
->GetHeight()-dh
);
247 if (win
->HasFlag(wxSUNKEN_BORDER
))
249 gtk_draw_shadow( widget
->style
,
254 win
->GetWidth()-dw
, win
->GetHeight()-dh
);
259 //-----------------------------------------------------------------------------
260 // "expose_event" of m_widget
261 //-----------------------------------------------------------------------------
263 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
265 if (gdk_event
->count
> 0) return;
266 draw_frame( widget
, win
);
269 //-----------------------------------------------------------------------------
270 // "draw" of m_wxwindow
271 //-----------------------------------------------------------------------------
273 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
275 draw_frame( widget
, win
);
278 #endif // GTK_MINOR_VERSION > 0
280 //-----------------------------------------------------------------------------
281 // "expose_event" of m_wxwindow
282 //-----------------------------------------------------------------------------
284 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
286 if ( !win
->HasVMT() )
289 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
291 gdk_event
->area
.width
,
292 gdk_event
->area
.height
);
294 if ( gdk_event
->count
> 0 )
298 printf( "OnExpose from " );
299 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
300 printf( win->GetClassInfo()->GetClassName() );
304 wxPaintEvent
event( win
->GetId() );
305 event
.SetEventObject( win
);
306 win
->GetEventHandler()->ProcessEvent( event
);
308 win
->GetUpdateRegion().Clear();
311 //-----------------------------------------------------------------------------
312 // "draw" of m_wxwindow
313 //-----------------------------------------------------------------------------
315 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
317 if ( !win
->HasVMT() )
320 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
321 rect
->width
, rect
->height
);
323 wxPaintEvent
event( win
->GetId() );
324 event
.SetEventObject( win
);
325 win
->GetEventHandler()->ProcessEvent( event
);
327 win
->GetUpdateRegion().Clear();
330 //-----------------------------------------------------------------------------
331 // "key_press_event" from any window
332 //-----------------------------------------------------------------------------
334 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
336 if (!win
->HasVMT()) return FALSE
;
337 if (g_blockEventsOnDrag
) return FALSE
;
340 printf( "OnKeyPress from " );
341 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
342 printf( win->GetClassInfo()->GetClassName() );
347 switch (gdk_event
->keyval
)
349 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
350 case GDK_ISO_Left_Tab
:
352 case GDK_Tab
: key_code
= WXK_TAB
; break;
353 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
354 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
355 case GDK_Return
: key_code
= WXK_RETURN
; break;
356 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
357 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
358 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
359 case GDK_Delete
: key_code
= WXK_DELETE
; break;
360 case GDK_Home
: key_code
= WXK_HOME
; break;
361 case GDK_Left
: key_code
= WXK_LEFT
; break;
362 case GDK_Up
: key_code
= WXK_UP
; break;
363 case GDK_Right
: key_code
= WXK_RIGHT
; break;
364 case GDK_Down
: key_code
= WXK_DOWN
; break;
365 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
366 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
367 case GDK_Next
: key_code
= WXK_NEXT
; break;
368 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
369 case GDK_End
: key_code
= WXK_END
; break;
370 case GDK_Begin
: key_code
= WXK_HOME
; break;
371 case GDK_Select
: key_code
= WXK_SELECT
; break;
372 case GDK_Print
: key_code
= WXK_PRINT
; break;
373 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
374 case GDK_Insert
: key_code
= WXK_INSERT
; break;
375 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
376 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
377 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
378 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
379 case GDK_KP_Up
: key_code
= WXK_UP
; break;
380 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
381 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
382 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
383 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
384 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
385 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
386 case GDK_KP_End
: key_code
= WXK_END
; break;
387 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
388 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
389 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
390 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
391 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
392 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
393 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
394 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
395 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
396 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
397 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
398 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
399 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
400 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
401 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
402 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
403 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
404 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
405 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
406 case GDK_F1
: key_code
= WXK_F1
; break;
407 case GDK_F2
: key_code
= WXK_F2
; break;
408 case GDK_F3
: key_code
= WXK_F3
; break;
409 case GDK_F4
: key_code
= WXK_F4
; break;
410 case GDK_F5
: key_code
= WXK_F5
; break;
411 case GDK_F6
: key_code
= WXK_F6
; break;
412 case GDK_F7
: key_code
= WXK_F7
; break;
413 case GDK_F8
: key_code
= WXK_F8
; break;
414 case GDK_F9
: key_code
= WXK_F9
; break;
415 case GDK_F10
: key_code
= WXK_F10
; break;
416 case GDK_F11
: key_code
= WXK_F11
; break;
417 case GDK_F12
: key_code
= WXK_F12
; break;
420 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
421 key_code
= gdk_event
->keyval
;
425 if (!key_code
) return FALSE
;
427 wxKeyEvent
event( wxEVT_KEY_DOWN
);
428 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
429 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
430 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
431 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
432 event
.m_keyCode
= key_code
;
435 event
.SetEventObject( win
);
437 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
441 wxWindow
*ancestor
= win
;
444 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
447 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
448 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
451 ancestor
= ancestor
->GetParent();
455 // win is a control: tab can be propagated up
457 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
458 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
460 wxNavigationKeyEvent new_event
;
461 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
462 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
463 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
464 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
465 new_event
.SetCurrentFocus( win
);
466 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
470 (gdk_event
->keyval
== GDK_Escape
) )
472 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
473 new_event
.SetEventObject( win
);
474 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
478 Damn, I forgot why this didn't work, but it didn't work.
480 // win is a panel: up can be propagated to the panel
481 if ((!ret) && (win->GetWxWindow()) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
482 (gdk_event->keyval == GDK_Up))
484 win->m_parent->SetFocus();
488 // win is a panel: left/right can be propagated to the panel
489 if ((!ret) && (win->GetWxWindow()) &&
490 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
491 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
493 wxNavigationKeyEvent new_event;
494 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
495 new_event.SetCurrentFocus( win );
496 ret = win->GetEventHandler()->ProcessEvent( new_event );
502 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
509 //-----------------------------------------------------------------------------
510 // "key_release_event" from any window
511 //-----------------------------------------------------------------------------
513 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
515 if (!win
->HasVMT()) return FALSE
;
516 if (g_blockEventsOnDrag
) return FALSE
;
519 printf( "OnKeyRelease from " );
520 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
521 printf( win->GetClassInfo()->GetClassName() );
526 switch (gdk_event
->keyval
)
528 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
529 case GDK_ISO_Left_Tab
:
531 case GDK_Tab
: key_code
= WXK_TAB
; break;
532 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
533 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
534 case GDK_Return
: key_code
= WXK_RETURN
; break;
535 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
536 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
537 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
538 case GDK_Delete
: key_code
= WXK_DELETE
; break;
539 case GDK_Home
: key_code
= WXK_HOME
; break;
540 case GDK_Left
: key_code
= WXK_LEFT
; break;
541 case GDK_Up
: key_code
= WXK_UP
; break;
542 case GDK_Right
: key_code
= WXK_RIGHT
; break;
543 case GDK_Down
: key_code
= WXK_DOWN
; break;
544 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
545 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
546 case GDK_Next
: key_code
= WXK_NEXT
; break;
547 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
548 case GDK_End
: key_code
= WXK_END
; break;
549 case GDK_Begin
: key_code
= WXK_HOME
; break;
550 case GDK_Select
: key_code
= WXK_SELECT
; break;
551 case GDK_Print
: key_code
= WXK_PRINT
; break;
552 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
553 case GDK_Insert
: key_code
= WXK_INSERT
; break;
554 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
555 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
556 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
557 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
558 case GDK_KP_Up
: key_code
= WXK_UP
; break;
559 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
560 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
561 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
562 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
563 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
564 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
565 case GDK_KP_End
: key_code
= WXK_END
; break;
566 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
567 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
568 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
569 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
570 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
571 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
572 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
573 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
574 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
575 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
576 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
577 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
578 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
579 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
580 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
581 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
582 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
583 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
584 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
585 case GDK_F1
: key_code
= WXK_F1
; break;
586 case GDK_F2
: key_code
= WXK_F2
; break;
587 case GDK_F3
: key_code
= WXK_F3
; break;
588 case GDK_F4
: key_code
= WXK_F4
; break;
589 case GDK_F5
: key_code
= WXK_F5
; break;
590 case GDK_F6
: key_code
= WXK_F6
; break;
591 case GDK_F7
: key_code
= WXK_F7
; break;
592 case GDK_F8
: key_code
= WXK_F8
; break;
593 case GDK_F9
: key_code
= WXK_F9
; break;
594 case GDK_F10
: key_code
= WXK_F10
; break;
595 case GDK_F11
: key_code
= WXK_F11
; break;
596 case GDK_F12
: key_code
= WXK_F12
; break;
599 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
600 key_code
= gdk_event
->keyval
;
604 if (!key_code
) return FALSE
;
606 wxKeyEvent
event( wxEVT_KEY_UP
);
607 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
608 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
609 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
610 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
611 event
.m_keyCode
= key_code
;
614 event
.SetEventObject( win
);
616 if (win
->GetEventHandler()->ProcessEvent( event
))
618 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
625 //-----------------------------------------------------------------------------
626 // "button_press_event"
627 //-----------------------------------------------------------------------------
629 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
631 if (!win
->HasVMT()) return FALSE
;
632 if (g_blockEventsOnDrag
) return TRUE
;
633 if (g_blockEventsOnScroll
) return TRUE
;
635 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
637 if (win
->GetWxWindow())
639 if (GTK_WIDGET_CAN_FOCUS(win
->GetWxWindow()) && !GTK_WIDGET_HAS_FOCUS (win
->GetWxWindow()) )
641 gtk_widget_grab_focus (win
->GetWxWindow());
644 printf( "GrabFocus from " );
645 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
646 printf( win->GetClassInfo()->GetClassName() );
654 printf( "OnButtonPress from " );
655 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
656 printf( win->GetClassInfo()->GetClassName() );
660 wxEventType event_type
= wxEVT_LEFT_DOWN
;
662 if (gdk_event
->button
== 1)
664 switch (gdk_event
->type
)
666 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
667 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
671 else if (gdk_event
->button
== 2)
673 switch (gdk_event
->type
)
675 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
676 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
680 else if (gdk_event
->button
== 3)
682 switch (gdk_event
->type
)
684 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
685 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
690 wxMouseEvent
event( event_type
);
691 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
692 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
693 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
694 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
695 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
696 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
697 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
699 event
.m_x
= (long)gdk_event
->x
;
700 event
.m_y
= (long)gdk_event
->y
;
702 // Some control don't have their own X window and thus cannot get
707 wxNode
*node
= win
->GetChildren().First();
710 wxWindow
*child
= (wxWindow
*)node
->Data();
712 if ( child
->IsStaticBox() )
714 // wxStaticBox is transparent in the box itself
718 wxRect
rectChild(child
->GetRect());
719 int xx1
= rectChild
.GetLeft(),
720 yy1
= rectChild
.GetTop(),
721 xx2
= rectChild
.GetRight(),
722 yy2
= rectChild
.GetBottom();
725 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
727 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
729 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
731 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
734 event
.m_x
-= child
->GetX();
735 event
.m_y
-= child
->GetY();
742 if ((child
->GetWxWindow() == (GtkWidget
*) NULL
) &&
743 (child
->GetX() <= event
.m_x
) &&
744 (child
->GetY() <= event
.m_y
) &&
745 (child
->GetX()+child
->GetWidth() >= event
.m_x
) &&
746 (child
->GetY()+child
->GetHeight() >= event
.m_y
))
749 event
.m_x
-= child
->GetX();
750 event
.m_y
-= child
->GetY();
758 event
.SetEventObject( win
);
760 gs_timeLastClick
= gdk_event
->time
;
762 if (win
->GetEventHandler()->ProcessEvent( event
))
764 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
771 //-----------------------------------------------------------------------------
772 // "button_release_event"
773 //-----------------------------------------------------------------------------
775 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
777 if (!win
->HasVMT()) return FALSE
;
778 if (g_blockEventsOnDrag
) return FALSE
;
779 if (g_blockEventsOnScroll
) return FALSE
;
781 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
784 printf( "OnButtonRelease from " );
785 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
786 printf( win->GetClassInfo()->GetClassName() );
790 wxEventType event_type
= wxEVT_NULL
;
792 switch (gdk_event
->button
)
794 case 1: event_type
= wxEVT_LEFT_UP
; break;
795 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
796 case 3: event_type
= wxEVT_RIGHT_UP
; break;
799 wxMouseEvent
event( event_type
);
800 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
801 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
802 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
803 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
804 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
805 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
806 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
807 event
.m_x
= (long)gdk_event
->x
;
808 event
.m_y
= (long)gdk_event
->y
;
810 // Some control don't have their own X window and thus cannot get
815 wxNode
*node
= win
->GetChildren().First();
818 wxWindow
*child
= (wxWindow
*)node
->Data();
820 if (child
->IsStaticBox() )
822 // wxStaticBox is transparent in the box itself
825 int xx1
= child
->GetX();
826 int yy1
= child
->GetY();
827 int xx2
= child
->GetX() + child
->GetWidth();
828 int yy2
= child
->GetX() + child
->GetHeight();
831 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
833 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
835 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
837 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
840 event
.m_x
-= child
->GetX();
841 event
.m_y
-= child
->GetY();
848 if ((child
->GetWxWindow() == (GtkWidget
*) NULL
) &&
849 (child
->GetX() <= event
.m_x
) &&
850 (child
->GetY() <= event
.m_y
) &&
851 (child
->GetX()+child
->GetWidth() >= event
.m_x
) &&
852 (child
->GetY()+child
->GetHeight() >= event
.m_y
))
855 event
.m_x
-= child
->GetX();
856 event
.m_y
-= child
->GetY();
864 event
.SetEventObject( win
);
866 if (win
->GetEventHandler()->ProcessEvent( event
))
868 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
875 //-----------------------------------------------------------------------------
876 // "motion_notify_event"
877 //-----------------------------------------------------------------------------
879 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
881 if (!win
->HasVMT()) return FALSE
;
882 if (g_blockEventsOnDrag
) return FALSE
;
883 if (g_blockEventsOnScroll
) return FALSE
;
885 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
887 if (gdk_event
->is_hint
)
891 GdkModifierType state
;
892 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
895 gdk_event
->state
= state
;
899 printf( "OnMotion from " );
900 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
901 printf( win->GetClassInfo()->GetClassName() );
905 wxMouseEvent
event( wxEVT_MOTION
);
906 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
907 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
908 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
909 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
910 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
911 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
912 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
914 event
.m_x
= (long)gdk_event
->x
;
915 event
.m_y
= (long)gdk_event
->y
;
917 // Some control don't have their own X window and thus cannot get
922 wxNode
*node
= win
->GetChildren().First();
925 wxWindow
*child
= (wxWindow
*)node
->Data();
927 if ( child
->IsStaticBox() )
929 // wxStaticBox is transparent in the box itself
932 int xx1
= child
->GetX();
933 int yy1
= child
->GetY();
934 int xx2
= child
->GetX() + child
->GetWidth();
935 int yy2
= child
->GetX() + child
->GetHeight();
938 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
940 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
942 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
944 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
947 event
.m_x
-= child
->GetX();
948 event
.m_y
-= child
->GetY();
955 if ((child
->GetWxWindow() == (GtkWidget
*) NULL
) &&
956 (child
->GetX() <= event
.m_x
) &&
957 (child
->GetY() <= event
.m_y
) &&
958 (child
->GetX()+child
->GetWidth() >= event
.m_x
) &&
959 (child
->GetY()+child
->GetHeight() >= event
.m_y
))
962 event
.m_x
-= child
->GetX();
963 event
.m_y
-= child
->GetY();
971 event
.SetEventObject( win
);
973 if (win
->GetEventHandler()->ProcessEvent( event
))
975 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
982 //-----------------------------------------------------------------------------
984 //-----------------------------------------------------------------------------
986 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
988 if (!win
->HasVMT()) return FALSE
;
989 if (g_blockEventsOnDrag
) return FALSE
;
993 if (win
->GetWxWindow())
995 if (GTK_WIDGET_CAN_FOCUS(win
->GetWxWindow()))
997 GTK_WIDGET_SET_FLAGS (win
->GetWxWindow(), GTK_HAS_FOCUS
);
999 printf( "SetFocus flag from " );
1000 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1001 printf( win->GetClassInfo()->GetClassName() );
1009 printf( "OnSetFocus from " );
1010 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1011 printf( win->GetClassInfo()->GetClassName() );
1013 printf( WXSTRINGCAST win->GetLabel() );
1017 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1018 event
.SetEventObject( win
);
1020 if (win
->GetEventHandler()->ProcessEvent( event
))
1022 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1029 //-----------------------------------------------------------------------------
1030 // "focus_out_event"
1031 //-----------------------------------------------------------------------------
1033 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1035 if (!win
->HasVMT()) return FALSE
;
1036 if (g_blockEventsOnDrag
) return FALSE
;
1038 if (win
->GetWxWindow())
1040 if (GTK_WIDGET_CAN_FOCUS(win
->GetWxWindow()))
1041 GTK_WIDGET_UNSET_FLAGS (win
->GetWxWindow(), GTK_HAS_FOCUS
);
1045 printf( "OnKillFocus from " );
1046 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1047 printf( win->GetClassInfo()->GetClassName() );
1051 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1052 event
.SetEventObject( win
);
1054 if (win
->GetEventHandler()->ProcessEvent( event
))
1056 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1063 //-----------------------------------------------------------------------------
1064 // "enter_notify_event"
1065 //-----------------------------------------------------------------------------
1067 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1069 if ( !win
->HasVMT() || g_blockEventsOnDrag
)
1072 GdkWindow
*window
= widget
->window
;
1073 if ( window
!= gdk_event
->window
)
1076 if ( window
&& win
->GetCursor().Ok() )
1077 gdk_window_set_cursor( window
, win
->GetCursor().GetCursor() );
1080 printf( "OnEnter from " );
1081 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1082 printf( win->GetClassInfo()->GetClassName() );
1086 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1087 event
.SetEventObject( win
);
1091 GdkModifierType state
= (GdkModifierType
)0;
1093 gdk_window_get_pointer( window
, &x
, &y
, &state
);
1095 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1096 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1097 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1098 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1099 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1100 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1101 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1103 event
.m_x
= (long)x
;
1104 event
.m_y
= (long)y
;
1106 if (win
->GetEventHandler()->ProcessEvent( event
))
1108 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1115 //-----------------------------------------------------------------------------
1116 // "leave_notify_event"
1117 //-----------------------------------------------------------------------------
1119 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1121 if ( !win
->HasVMT() || g_blockEventsOnDrag
)
1124 GdkWindow
*window
= widget
->window
;
1125 if ( window
!= gdk_event
->window
)
1128 if ( window
&& win
->GetCursor().Ok() )
1129 gdk_window_set_cursor( window
, wxSTANDARD_CURSOR
->GetCursor() );
1132 printf( "OnLeave from " );
1133 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1134 printf( win->GetClassInfo()->GetClassName() );
1138 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1139 event
.SetEventObject( win
);
1143 GdkModifierType state
= (GdkModifierType
)0;
1145 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1147 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1148 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1149 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1150 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1151 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1152 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1153 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1155 event
.m_x
= (long)x
;
1156 event
.m_y
= (long)y
;
1158 if (win
->GetEventHandler()->ProcessEvent( event
))
1160 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1167 //-----------------------------------------------------------------------------
1168 // "value_changed" from m_vAdjust
1169 //-----------------------------------------------------------------------------
1171 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1173 if (g_blockEventsOnDrag
) return;
1176 printf( "OnVScroll from " );
1177 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1178 printf( win->GetClassInfo()->GetClassName() );
1182 if (!win
->HasVMT()) return;
1184 float diff
= win
->GetVAdjust()->value
- win
->GetOldVerticalPos();
1185 if (fabs(diff
) < 0.2) return;
1186 win
->SetOldVerticalPos(win
->GetVAdjust()->value
);
1188 wxEventType command
= wxEVT_NULL
;
1190 float line_step
= win
->GetVAdjust()->step_increment
;
1191 float page_step
= win
->GetVAdjust()->page_increment
;
1193 if (win
->IsScrolling())
1195 command
= wxEVT_SCROLL_THUMBTRACK
;
1199 if (fabs(win
->GetVAdjust()->value
-win
->GetVAdjust()->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1200 else if (fabs(win
->GetVAdjust()->value
-win
->GetVAdjust()->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1201 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1202 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1203 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1204 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1205 else command
= wxEVT_SCROLL_THUMBTRACK
;
1208 int value
= (int)(win
->GetVAdjust()->value
+0.5);
1210 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1211 event
.SetEventObject( win
);
1212 win
->GetEventHandler()->ProcessEvent( event
);
1215 //-----------------------------------------------------------------------------
1216 // "value_changed" from m_hAdjust
1217 //-----------------------------------------------------------------------------
1219 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1221 if (g_blockEventsOnDrag
) return;
1224 printf( "OnHScroll from " );
1225 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1226 printf( win->GetClassInfo()->GetClassName() );
1230 if (!win
->HasVMT()) return;
1232 float diff
= win
->GetHAdjust()->value
- win
->GetOldHorizontalPos();
1233 if (fabs(diff
) < 0.2) return;
1234 win
->SetOldHorizontalPos( win
->GetHAdjust()->value
);
1236 wxEventType command
= wxEVT_NULL
;
1238 float line_step
= win
->GetHAdjust()->step_increment
;
1239 float page_step
= win
->GetHAdjust()->page_increment
;
1241 if (win
->IsScrolling())
1243 command
= wxEVT_SCROLL_THUMBTRACK
;
1247 if (fabs(win
->GetHAdjust()->value
-win
->GetHAdjust()->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1248 else if (fabs(win
->GetHAdjust()->value
-win
->GetHAdjust()->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1249 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1250 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1251 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1252 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1253 else command
= wxEVT_SCROLL_THUMBTRACK
;
1256 int value
= (int)(win
->GetHAdjust()->value
+0.5);
1258 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1259 event
.SetEventObject( win
);
1260 win
->GetEventHandler()->ProcessEvent( event
);
1263 //-----------------------------------------------------------------------------
1264 // "changed" from m_vAdjust
1265 //-----------------------------------------------------------------------------
1267 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1269 if (g_blockEventsOnDrag
) return;
1272 printf( "OnVScroll change from " );
1273 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1274 printf( win->GetClassInfo()->GetClassName() );
1278 if (!win
->HasVMT()) return;
1280 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1281 int value
= (int)(win
->GetVAdjust()->value
+0.5);
1283 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1284 event
.SetEventObject( win
);
1285 win
->GetEventHandler()->ProcessEvent( event
);
1288 //-----------------------------------------------------------------------------
1289 // "changed" from m_hAdjust
1290 //-----------------------------------------------------------------------------
1292 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1294 if (g_blockEventsOnDrag
) return;
1297 printf( "OnHScroll change from " );
1298 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1299 printf( win->GetClassInfo()->GetClassName() );
1303 if (!win
->HasVMT()) return;
1305 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1306 int value
= (int)(win
->GetHAdjust()->value
+0.5);
1308 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1309 event
.SetEventObject( win
);
1310 win
->GetEventHandler()->ProcessEvent( event
);
1313 //-----------------------------------------------------------------------------
1314 // "button_press_event" from scrollbar
1315 //-----------------------------------------------------------------------------
1317 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1318 GdkEventButton
*WXUNUSED(gdk_event
),
1321 // don't test here as we can release the mouse while being over
1322 // a different window then the slider
1324 // if (gdk_event->window != widget->slider) return FALSE;
1326 win
->SetScrolling( TRUE
);
1331 //-----------------------------------------------------------------------------
1332 // "button_release_event" from scrollbar
1333 //-----------------------------------------------------------------------------
1335 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1336 GdkEventButton
*WXUNUSED(gdk_event
),
1340 // don't test here as we can release the mouse while being over
1341 // a different window then the slider
1343 // if (gdk_event->window != widget->slider) return FALSE;
1345 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->GetHandle());
1347 if (widget
== GTK_RANGE(scrolledWindow
->vscrollbar
))
1348 gtk_signal_emit_by_name( GTK_OBJECT(win
->GetHAdjust()), "value_changed" );
1350 gtk_signal_emit_by_name( GTK_OBJECT(win
->GetVAdjust()), "value_changed" );
1352 win
->SetScrolling( FALSE
);
1357 // ----------------------------------------------------------------------------
1358 // this wxWindowBase function is implemented here (in platform-specific file)
1359 // because it is static and so couldn't be made virtual
1360 // ----------------------------------------------------------------------------
1362 wxWindow
*wxWindowBase::FindFocus()
1364 return g_focusWindow
;
1367 //-----------------------------------------------------------------------------
1368 // InsertChild for wxWindow.
1369 //-----------------------------------------------------------------------------
1371 /* Callback for wxWindow. This very strange beast has to be used because
1372 * C++ has no virtual methods in a constructor. We have to emulate a
1373 * virtual function here as wxNotebook requires a different way to insert
1374 * a child in it. I had opted for creating a wxNotebookPage window class
1375 * which would have made this superfluous (such in the MDI window system),
1376 * but no-one was listening to me... */
1378 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1380 gtk_myfixed_put( GTK_MYFIXED(parent
->GetWxWindow()),
1381 GTK_WIDGET(child
->GetHandle()),
1385 child
->GetHeight() );
1387 gtk_widget_set_usize( GTK_WIDGET(child
->GetHandle()),
1389 child
->GetHeight() );
1391 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1393 /* we now allow a window to get the focus as long as it
1394 doesn't have any children. */
1395 GTK_WIDGET_UNSET_FLAGS( parent
->GetWxWindow(), GTK_CAN_FOCUS
);
1399 //-----------------------------------------------------------------------------
1401 //-----------------------------------------------------------------------------
1403 wxWindow
* wxGetActiveWindow()
1405 return g_focusWindow
;
1408 //-----------------------------------------------------------------------------
1410 //-----------------------------------------------------------------------------
1412 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1414 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
)
1415 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1418 void wxWindow::Init()
1424 m_wxwindow
= (GtkWidget
*) NULL
;
1432 m_font
= *wxSWISS_FONT
;
1433 m_windowName
= "noname";
1437 m_needParent
= TRUE
;
1440 m_isScrolling
= FALSE
;
1443 m_vAdjust
= (GtkAdjustment
*) NULL
;
1444 m_oldHorizontalPos
=
1445 m_oldVerticalPos
= 0.0;
1448 m_scrollGC
= (GdkGC
*) NULL
;
1449 m_widgetStyle
= (GtkStyle
*) NULL
;
1451 m_insertCallback
= wxInsertChildInWindow
;
1453 m_isStaticBox
= FALSE
;
1454 m_acceptsFocus
= FALSE
;
1457 wxWindow::wxWindow()
1462 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1463 const wxPoint
&pos
, const wxSize
&size
,
1464 long style
, const wxString
&name
)
1468 Create( parent
, id
, pos
, size
, style
, name
);
1471 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1472 const wxPoint
&pos
, const wxSize
&size
,
1473 long style
, const wxString
&name
)
1475 PreCreation( parent
, id
, pos
, size
, style
, name
);
1477 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1478 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1481 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1484 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1487 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1488 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1491 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1492 scroll_class
->scrollbar_spacing
= 0;
1494 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1496 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1497 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1499 m_wxwindow
= gtk_myfixed_new();
1502 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1505 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1507 #if (GTK_MINOR_VERSION > 0)
1508 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1510 if (HasFlag(wxRAISED_BORDER
))
1512 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1514 else if (HasFlag(wxSUNKEN_BORDER
))
1516 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1520 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1522 #else // GTK_MINOR_VERSION == 0
1523 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1525 if (HasFlag(wxRAISED_BORDER
))
1527 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1529 else if (HasFlag(wxSUNKEN_BORDER
))
1531 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1535 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1537 #endif // GTK_MINOR_VERSION
1539 if (HasFlag(wxTAB_TRAVERSAL
))
1541 /* we now allow a window to get the focus as long as it
1542 doesn't have any children. */
1543 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1544 m_acceptsFocus
= FALSE
;
1548 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1549 m_acceptsFocus
= TRUE
;
1552 #if (GTK_MINOR_VERSION == 0)
1553 // shut the viewport up
1554 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1555 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1556 #endif // GTK_MINOR_VERSION == 0
1558 // I _really_ don't want scrollbars in the beginning
1559 InitAdjustment(m_vAdjust
);
1560 InitAdjustment(m_hAdjust
);
1562 // these handlers block mouse events to any window during scrolling such as
1563 // motion events and prevent GTK and wxWindows from fighting over where the
1566 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1567 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1569 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1570 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1572 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1573 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1575 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1576 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1578 // these handlers get notified when screen updates are required either when
1579 // scrolling or when the window size (and therefore scrollbar configuration)
1582 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1583 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1584 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1585 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1587 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1588 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1589 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1590 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1592 gtk_widget_show( m_wxwindow
);
1595 m_parent
->DoAddChild( this );
1604 wxWindow::~wxWindow()
1612 m_parent
->RemoveChild( this );
1615 gtk_style_unref( m_widgetStyle
);
1618 gdk_gc_unref( m_scrollGC
);
1621 gtk_widget_destroy( m_wxwindow
);
1624 gtk_widget_destroy( m_widget
);
1627 void wxWindow::PreCreation( wxWindow
*parent
,
1632 const wxString
&name
)
1634 wxASSERT_MSG( !m_needParent
|| parent
, _T("Need complete parent.") );
1636 if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) )
1638 wxFAIL_MSG(_T("window creation failed"));
1641 m_width
= WidthDefault(size
.x
);
1642 m_height
= HeightDefault(size
.y
);
1647 if (!parent
) /* some reasonable defaults */
1651 m_x
= (gdk_screen_width () - m_width
) / 2;
1652 if (m_x
< 10) m_x
= 10;
1656 m_y
= (gdk_screen_height () - m_height
) / 2;
1657 if (m_y
< 10) m_y
= 10;
1662 void wxWindow::PostCreation()
1664 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1668 /* these get reported to wxWindows -> wxPaintEvent */
1669 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1670 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1672 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1673 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1675 #if (GTK_MINOR_VERSION > 0)
1676 /* these are called when the "sunken" or "raised" borders are drawn */
1677 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1678 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1680 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1681 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1685 ConnectWidget( GetConnectWidget() );
1687 /* we force the creation of wxFrame and wxDialog in the respective code */
1689 gtk_widget_realize( m_widget
);
1692 gtk_widget_realize( m_wxwindow
);
1694 SetCursor( *wxSTANDARD_CURSOR
);
1699 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1701 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1702 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1704 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1705 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1707 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1708 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1710 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1711 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1713 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1714 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1716 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1717 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1719 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1720 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1722 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1723 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1725 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1726 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1729 bool wxWindow::Destroy()
1731 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1735 return wxWindowBase::Destroy();
1738 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1740 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1741 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1743 if (m_resizing
) return; /* I don't like recursions */
1746 if (m_parent
->GetWxWindow() == NULL
) /* i.e. wxNotebook */
1748 /* don't set the size for children of wxNotebook, just take the values. */
1756 int old_width
= m_width
;
1757 int old_height
= m_height
;
1759 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1761 if (x
!= -1) m_x
= x
;
1762 if (y
!= -1) m_y
= y
;
1763 if (width
!= -1) m_width
= width
;
1764 if (height
!= -1) m_height
= height
;
1774 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1776 if (width
== -1) m_width
= 80;
1779 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1781 if (height
== -1) m_height
= 26;
1784 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1785 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1786 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1787 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1789 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1791 /* the default button has a border around it */
1794 gtk_myfixed_move( GTK_MYFIXED(m_parent
->GetWxWindow()), m_widget
, m_x
-border
, m_y
-border
);
1796 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1800 gtk_myfixed_move( GTK_MYFIXED(m_parent
->GetWxWindow()), m_widget
, m_x
, m_y
);
1802 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1803 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1809 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1810 event
.SetEventObject( this );
1811 GetEventHandler()->ProcessEvent( event
);
1816 void wxWindow::OnInternalIdle()
1821 void wxWindow::DoGetSize( int *width
, int *height
) const
1823 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1825 if (width
) (*width
) = m_width
;
1826 if (height
) (*height
) = m_height
;
1829 void wxWindow::DoSetClientSize( int width
, int height
)
1831 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1835 SetSize( width
, height
);
1842 if (!m_hasScrolling
)
1844 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1846 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1848 dw
+= 2 * window_class
->xthickness
;
1849 dh
+= 2 * window_class
->ythickness
;
1854 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1855 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1857 #if (GTK_MINOR_VERSION == 0)
1858 GtkWidget
*viewport
= scroll_window
->viewport
;
1859 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1861 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1863 dw
+= 2 * viewport_class
->xthickness
;
1864 dh
+= 2 * viewport_class
->ythickness
;
1869 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1870 GtkWidget *vscrollbar = scroll_window->vscrollbar;
1872 we use this instead: range.slider_width = 11 + 2*2pts edge
1875 if (scroll_window
->vscrollbar_visible
)
1877 dw
+= 15; /* dw += vscrollbar->allocation.width; */
1878 dw
+= scroll_class
->scrollbar_spacing
;
1881 if (scroll_window
->hscrollbar_visible
)
1883 dh
+= 15; /* dh += hscrollbar->allocation.height; */
1884 dw
+= scroll_class
->scrollbar_spacing
;
1888 SetSize( width
+dw
, height
+dh
);
1892 void wxWindow::DoGetClientSize( int *width
, int *height
) const
1894 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1898 if (width
) (*width
) = m_width
;
1899 if (height
) (*height
) = m_height
;
1906 if (!m_hasScrolling
)
1908 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1910 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1912 dw
+= 2 * window_class
->xthickness
;
1913 dh
+= 2 * window_class
->ythickness
;
1918 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1919 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1921 #if (GTK_MINOR_VERSION == 0)
1922 GtkWidget
*viewport
= scroll_window
->viewport
;
1923 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1925 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) )
1927 dw
+= 2 * viewport_class
->xthickness
;
1928 dh
+= 2 * viewport_class
->ythickness
;
1932 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1933 GtkWidget *vscrollbar = scroll_window->vscrollbar;
1935 we use this instead: range.slider_width = 11 + 2*2pts edge
1938 if (scroll_window
->vscrollbar_visible
)
1940 dw
+= 15; /* dw += vscrollbar->allocation.width; */
1941 dw
+= scroll_class
->scrollbar_spacing
;
1944 if (scroll_window
->hscrollbar_visible
)
1946 dh
+= 15; /* dh += hscrollbar->allocation.height; */
1947 dh
+= scroll_class
->scrollbar_spacing
;
1951 if (width
) (*width
) = m_width
- dw
;
1952 if (height
) (*height
) = m_height
- dh
;
1956 void wxWindow::DoGetPosition( int *x
, int *y
) const
1958 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1964 void wxWindow::ClientToScreen( int *x
, int *y
) const
1966 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1968 GdkWindow
*source
= (GdkWindow
*) NULL
;
1970 source
= m_wxwindow
->window
;
1972 source
= m_widget
->window
;
1976 gdk_window_get_origin( source
, &org_x
, &org_y
);
1980 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1982 org_x
+= m_widget
->allocation
.x
;
1983 org_y
+= m_widget
->allocation
.y
;
1991 void wxWindow::ScreenToClient( int *x
, int *y
) const
1993 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1995 GdkWindow
*source
= (GdkWindow
*) NULL
;
1997 source
= m_wxwindow
->window
;
1999 source
= m_widget
->window
;
2003 gdk_window_get_origin( source
, &org_x
, &org_y
);
2007 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2009 org_x
+= m_widget
->allocation
.x
;
2010 org_y
+= m_widget
->allocation
.y
;
2018 bool wxWindow::Show( bool show
)
2020 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2022 if ( !wxWindowBase::Show(show
) )
2026 gtk_widget_show( m_widget
);
2028 gtk_widget_hide( m_widget
);
2033 bool wxWindow::Enable( bool enable
)
2035 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2037 if ( !wxWindowBase::Enable(enable
) )
2040 gtk_widget_set_sensitive( m_widget
, enable
);
2042 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2047 int wxWindow::GetCharHeight() const
2049 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2051 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2053 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2055 return font
->ascent
+ font
->descent
;
2058 int wxWindow::GetCharWidth() const
2060 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2062 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2064 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2066 return gdk_string_width( font
, "H" );
2069 void wxWindow::GetTextExtent( const wxString
& string
,
2073 int *externalLeading
,
2074 const wxFont
*theFont
) const
2076 wxFont fontToUse
= m_font
;
2077 if (theFont
) fontToUse
= *theFont
;
2079 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2081 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2082 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2083 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2084 if (descent
) (*descent
) = font
->descent
;
2085 if (externalLeading
) (*externalLeading
) = 0; // ??
2088 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2090 event
.SetEventType( wxEVT_CHAR
);
2092 if (!GetEventHandler()->ProcessEvent( event
))
2098 void wxWindow::SetFocus()
2100 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2102 GtkWidget
*connect_widget
= GetConnectWidget();
2105 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2107 gtk_widget_grab_focus (connect_widget
);
2109 else if (GTK_IS_CONTAINER(connect_widget
))
2111 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2119 bool wxWindow::AcceptsFocus() const
2121 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2124 bool wxWindow::Reparent( wxWindow
*newParent
)
2126 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2128 if ( !wxWindowBase::Reparent(newParent
) )
2131 gtk_widget_unparent( m_widget
);
2136 void wxWindow::Raise()
2138 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2140 gdk_window_raise( m_widget
->window
);
2143 void wxWindow::Lower()
2145 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2147 gdk_window_lower( m_widget
->window
);
2150 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2152 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2154 if ( wxWindowBase::SetCursor(cursor
) )
2156 if ((m_widget
) && (m_widget
->window
))
2157 gdk_window_set_cursor( m_widget
->window
, GetCursor().GetCursor() );
2159 if ((m_wxwindow
) && (m_wxwindow
->window
))
2160 gdk_window_set_cursor( m_wxwindow
->window
, GetCursor().GetCursor() );
2167 // cursor hasn't been changed
2172 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2177 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2179 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2181 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2185 gdk_window_clear_area( m_wxwindow
->window
,
2187 rect
->width
, rect
->height
);
2191 gdk_window_clear( m_wxwindow
->window
);
2198 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2200 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2204 GdkRectangle gdk_rect
;
2205 gdk_rect
.x
= rect
->x
;
2206 gdk_rect
.y
= rect
->y
;
2207 gdk_rect
.width
= rect
->width
;
2208 gdk_rect
.height
= rect
->height
;
2211 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2213 gtk_widget_draw( m_widget
, &gdk_rect
);
2217 void wxWindow::Clear()
2219 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2221 if (m_wxwindow
&& m_wxwindow
->window
)
2223 gdk_window_clear( m_wxwindow
->window
);
2228 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2230 wxWindowBase::DoSetToolTip(tip
);
2233 m_tooltip
->Apply( this );
2236 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2238 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2240 #endif // wxUSE_TOOLTIPS
2242 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2244 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2246 if ( !wxWindowBase::SetBackgroundColour(colour
) )
2249 if (m_wxwindow
&& m_wxwindow
->window
)
2251 // wxMSW doesn't clear the window here. I don't do that either to
2252 // provide compatibility. call Clear() to do the job.
2254 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2255 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2258 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2260 if ( sysbg
== m_backgroundColour
)
2262 m_backgroundColour
= wxNullColour
;
2264 m_backgroundColour
= sysbg
;
2274 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2276 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2278 if ( !wxWindowBase::SetForegroundColour(colour
) )
2281 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2282 if ( sysbg
== m_foregroundColour
)
2284 m_backgroundColour
= wxNullColour
;
2286 m_backgroundColour
= sysbg
;
2296 GtkStyle
*wxWindow::GetWidgetStyle()
2298 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2300 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2302 return m_widgetStyle
;
2305 void wxWindow::SetWidgetStyle()
2307 GtkStyle
*style
= GetWidgetStyle();
2309 gdk_font_unref( style
->font
);
2310 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2312 if (m_foregroundColour
.Ok())
2314 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2315 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2316 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2317 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2320 if (m_backgroundColour
.Ok())
2322 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2323 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2324 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2325 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2326 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2327 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2328 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2329 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2330 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2334 void wxWindow::ApplyWidgetStyle()
2338 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2340 menu
->SetInvokingWindow( win
);
2341 wxNode
*node
= menu
->GetItems().First();
2344 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2345 if (menuitem
->IsSubMenu())
2347 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2349 node
= node
->Next();
2353 static gint gs_pop_x
= 0;
2354 static gint gs_pop_y
= 0;
2356 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2358 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2363 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2365 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2367 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2369 SetInvokingWindow( menu
, this );
2377 GTK_MENU(menu
->m_menu
),
2378 (GtkWidget
*) NULL
, // parent menu shell
2379 (GtkWidget
*) NULL
, // parent menu item
2380 (GtkMenuPositionFunc
) pop_pos_callback
,
2381 (gpointer
) this, // client data
2382 0, // button used to activate it
2383 0 //gs_timeLastClick // the time of activation
2388 #if wxUSE_DRAG_AND_DROP
2390 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2392 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2394 GtkWidget
*dnd_widget
= GetConnectWidget();
2396 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2398 if (m_dropTarget
) delete m_dropTarget
;
2399 m_dropTarget
= dropTarget
;
2401 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2404 #endif // wxUSE_DRAG_AND_DROP
2406 GtkWidget
* wxWindow::GetConnectWidget()
2408 GtkWidget
*connect_widget
= m_widget
;
2409 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2411 return connect_widget
;
2414 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2416 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2417 return (window
== m_widget
->window
);
2420 bool wxWindow::SetFont( const wxFont
&font
)
2422 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2424 if ( !wxWindowBase::SetFont(font
) )
2430 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2431 if ( sysbg
== m_backgroundColour
)
2433 m_backgroundColour
= wxNullColour
;
2435 m_backgroundColour
= sysbg
;
2445 void wxWindow::CaptureMouse()
2447 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2449 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
2451 GtkWidget
*connect_widget
= GetConnectWidget();
2452 gtk_grab_add( connect_widget
);
2453 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2455 (GDK_BUTTON_PRESS_MASK
|
2456 GDK_BUTTON_RELEASE_MASK
|
2457 GDK_POINTER_MOTION_MASK
),
2464 void wxWindow::ReleaseMouse()
2466 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2468 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
2470 GtkWidget
*connect_widget
= GetConnectWidget();
2471 gtk_grab_remove( connect_widget
);
2472 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2473 g_capturing
= FALSE
;
2476 bool wxWindow::IsRetained() const
2481 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2482 int range
, bool refresh
)
2484 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2486 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2488 m_hasScrolling
= TRUE
;
2490 if (orient
== wxHORIZONTAL
)
2492 float fpos
= (float)pos
;
2493 float frange
= (float)range
;
2494 float fthumb
= (float)thumbVisible
;
2495 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2496 if (fpos
< 0.0) fpos
= 0.0;
2498 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2499 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2501 SetScrollPos( orient
, pos
, refresh
);
2505 m_oldHorizontalPos
= fpos
;
2507 m_hAdjust
->lower
= 0.0;
2508 m_hAdjust
->upper
= frange
;
2509 m_hAdjust
->value
= fpos
;
2510 m_hAdjust
->step_increment
= 1.0;
2511 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2512 m_hAdjust
->page_size
= fthumb
;
2516 float fpos
= (float)pos
;
2517 float frange
= (float)range
;
2518 float fthumb
= (float)thumbVisible
;
2519 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2520 if (fpos
< 0.0) fpos
= 0.0;
2522 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2523 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2525 SetScrollPos( orient
, pos
, refresh
);
2529 m_oldVerticalPos
= fpos
;
2531 m_vAdjust
->lower
= 0.0;
2532 m_vAdjust
->upper
= frange
;
2533 m_vAdjust
->value
= fpos
;
2534 m_vAdjust
->step_increment
= 1.0;
2535 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2536 m_vAdjust
->page_size
= fthumb
;
2539 if (m_wxwindow
->window
)
2541 if (orient
== wxHORIZONTAL
)
2542 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2544 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2546 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2550 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2552 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2554 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2556 if (orient
== wxHORIZONTAL
)
2558 float fpos
= (float)pos
;
2559 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2560 if (fpos
< 0.0) fpos
= 0.0;
2561 m_oldHorizontalPos
= fpos
;
2563 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2564 m_hAdjust
->value
= fpos
;
2568 float fpos
= (float)pos
;
2569 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2570 if (fpos
< 0.0) fpos
= 0.0;
2571 m_oldVerticalPos
= fpos
;
2573 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2574 m_vAdjust
->value
= fpos
;
2579 if (m_wxwindow
->window
)
2581 if (orient
== wxHORIZONTAL
)
2582 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2584 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2589 int wxWindow::GetScrollThumb( int orient
) const
2591 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2593 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2595 if (orient
== wxHORIZONTAL
)
2596 return (int)(m_hAdjust
->page_size
+0.5);
2598 return (int)(m_vAdjust
->page_size
+0.5);
2601 int wxWindow::GetScrollPos( int orient
) const
2603 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2605 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2607 if (orient
== wxHORIZONTAL
)
2608 return (int)(m_hAdjust
->value
+0.5);
2610 return (int)(m_vAdjust
->value
+0.5);
2613 int wxWindow::GetScrollRange( int orient
) const
2615 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2617 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2619 if (orient
== wxHORIZONTAL
)
2620 return (int)(m_hAdjust
->upper
+0.5);
2622 return (int)(m_vAdjust
->upper
+0.5);
2625 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2627 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2629 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2631 wxNode
*node
= m_children
.First();
2634 wxWindow
*child
= (wxWindow
*) node
->Data();
2635 child
->Move( child
->GetX() + dx
, child
->GetY() + dy
);
2636 node
= node
->Next();
2641 GetClientSize( &cw
, &ch
);
2643 int w
= cw
- abs(dx
);
2644 int h
= ch
- abs(dy
);
2645 if ((h
< 0) || (w
< 0))
2652 if (dx
< 0) s_x
= -dx
;
2653 if (dy
< 0) s_y
= -dy
;
2656 if (dx
> 0) d_x
= dx
;
2657 if (dy
> 0) d_y
= dy
;
2661 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2662 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2665 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2666 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2669 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2670 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2671 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2672 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2674 Refresh( TRUE
, &rect
);
2677 void wxWindow::SetScrolling(bool scroll
)
2679 m_isScrolling
= g_blockEventsOnScroll
= scroll
;