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
),
149 static bool s_done = FALSE;
152 wxLog::AddTraceMask("focus");
155 wxLogTrace(_T("FOCUS NOW AT: %s"), name);
161 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
167 wxChar
*s
= new wxChar
[tmp
.Length()+1];
171 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
172 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
177 //-----------------------------------------------------------------------------
179 //-----------------------------------------------------------------------------
181 extern void wxapp_install_idle_handler();
182 extern bool g_isIdle
;
184 //-----------------------------------------------------------------------------
185 // local code (see below)
186 //-----------------------------------------------------------------------------
188 #if (GTK_MINOR_VERSION > 0)
190 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
198 if (win
->HasScrolling())
200 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
201 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
204 GtkWidget *hscrollbar = scroll_window->hscrollbar;
205 GtkWidget *vscrollbar = scroll_window->vscrollbar;
207 we use this instead: range.slider_width = 11 + 2*2pts edge
210 if (scroll_window
->vscrollbar_visible
)
212 dw
+= 15; /* dw += vscrollbar->allocation.width; */
213 dw
+= scroll_class
->scrollbar_spacing
;
216 if (scroll_window
->hscrollbar_visible
)
218 dh
+= 15; /* dh += hscrollbar->allocation.height; */
219 dw
+= scroll_class
->scrollbar_spacing
;
225 if (GTK_WIDGET_NO_WINDOW (widget
))
227 dx
+= widget
->allocation
.x
;
228 dy
+= widget
->allocation
.y
;
231 if (win
->HasFlag(wxRAISED_BORDER
))
233 gtk_draw_shadow( widget
->style
,
238 win
->m_width
-dw
, win
->m_height
-dh
);
242 if (win
->HasFlag(wxSUNKEN_BORDER
))
244 gtk_draw_shadow( widget
->style
,
249 win
->m_width
-dw
, win
->m_height
-dh
);
254 //-----------------------------------------------------------------------------
255 // "expose_event" of m_widget
256 //-----------------------------------------------------------------------------
258 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
260 if (gdk_event
->count
> 0) return;
261 draw_frame( widget
, win
);
264 //-----------------------------------------------------------------------------
265 // "draw" of m_wxwindow
266 //-----------------------------------------------------------------------------
268 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
270 draw_frame( widget
, win
);
273 #endif // GTK_MINOR_VERSION > 0
275 //-----------------------------------------------------------------------------
276 // "expose_event" of m_wxwindow
277 //-----------------------------------------------------------------------------
279 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
281 if ( !win
->m_hasVMT
)
284 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
286 gdk_event
->area
.width
,
287 gdk_event
->area
.height
);
289 if ( gdk_event
->count
> 0 )
293 printf( "OnExpose from " );
294 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
295 printf( win->GetClassInfo()->GetClassName() );
299 wxPaintEvent
event( win
->GetId() );
300 event
.SetEventObject( win
);
301 win
->GetEventHandler()->ProcessEvent( event
);
303 win
->GetUpdateRegion().Clear();
306 //-----------------------------------------------------------------------------
307 // "draw" of m_wxwindow
308 //-----------------------------------------------------------------------------
310 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
313 wxapp_install_idle_handler();
318 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
319 rect
->width
, rect
->height
);
321 wxPaintEvent
event( win
->GetId() );
322 event
.SetEventObject( win
);
323 win
->GetEventHandler()->ProcessEvent( event
);
325 win
->GetUpdateRegion().Clear();
328 //-----------------------------------------------------------------------------
329 // "key_press_event" from any window
330 //-----------------------------------------------------------------------------
332 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
335 wxapp_install_idle_handler();
337 if (!win
->m_hasVMT
) return FALSE
;
338 if (g_blockEventsOnDrag
) return FALSE
;
341 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
342 if (gdk_event->state & GDK_SHIFT_MASK)
343 printf( "ShiftDown.\n" );
345 printf( "ShiftUp.\n" );
346 if (gdk_event->state & GDK_CONTROL_MASK)
347 printf( "ControlDown.\n" );
349 printf( "ControlUp.\n" );
354 switch (gdk_event
->keyval
)
357 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
359 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
360 case GDK_Menu
: key_code
= WXK_MENU
; break;
361 case GDK_Help
: key_code
= WXK_HELP
; break;
362 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
363 case GDK_ISO_Left_Tab
:
365 case GDK_Tab
: key_code
= WXK_TAB
; break;
366 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
367 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
368 case GDK_Return
: key_code
= WXK_RETURN
; break;
369 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
370 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
371 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
372 case GDK_Delete
: key_code
= WXK_DELETE
; break;
373 case GDK_Home
: key_code
= WXK_HOME
; break;
374 case GDK_Left
: key_code
= WXK_LEFT
; break;
375 case GDK_Up
: key_code
= WXK_UP
; break;
376 case GDK_Right
: key_code
= WXK_RIGHT
; break;
377 case GDK_Down
: key_code
= WXK_DOWN
; break;
378 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
379 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
380 case GDK_Next
: key_code
= WXK_NEXT
; break;
381 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
382 case GDK_End
: key_code
= WXK_END
; break;
383 case GDK_Begin
: key_code
= WXK_HOME
; break;
384 case GDK_Select
: key_code
= WXK_SELECT
; break;
385 case GDK_Print
: key_code
= WXK_PRINT
; break;
386 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
387 case GDK_Insert
: key_code
= WXK_INSERT
; break;
388 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
389 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
390 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
391 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
392 case GDK_KP_Up
: key_code
= WXK_UP
; break;
393 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
394 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
395 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
396 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
397 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
398 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
399 case GDK_KP_End
: key_code
= WXK_END
; break;
400 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
401 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
402 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
403 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
404 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
405 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
406 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
407 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
408 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
409 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
410 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
411 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
412 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
413 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
414 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
415 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
416 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
417 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
418 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
419 case GDK_F1
: key_code
= WXK_F1
; break;
420 case GDK_F2
: key_code
= WXK_F2
; break;
421 case GDK_F3
: key_code
= WXK_F3
; break;
422 case GDK_F4
: key_code
= WXK_F4
; break;
423 case GDK_F5
: key_code
= WXK_F5
; break;
424 case GDK_F6
: key_code
= WXK_F6
; break;
425 case GDK_F7
: key_code
= WXK_F7
; break;
426 case GDK_F8
: key_code
= WXK_F8
; break;
427 case GDK_F9
: key_code
= WXK_F9
; break;
428 case GDK_F10
: key_code
= WXK_F10
; break;
429 case GDK_F11
: key_code
= WXK_F11
; break;
430 case GDK_F12
: key_code
= WXK_F12
; break;
433 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
434 key_code
= gdk_event
->keyval
;
440 GdkModifierType state
;
441 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
443 wxKeyEvent
event( wxEVT_KEY_DOWN
);
444 event
.SetTimestamp( gdk_event
->time
);
445 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
446 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
447 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
448 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
449 event
.m_keyCode
= key_code
;
450 event
.m_scanCode
= gdk_event
->keyval
;
453 event
.SetEventObject( win
);
455 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
459 wxWindow
*ancestor
= win
;
462 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
465 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
466 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
469 ancestor
= ancestor
->GetParent();
473 // win is a control: tab can be propagated up
475 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
476 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
478 wxNavigationKeyEvent new_event
;
479 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
480 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
481 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
482 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
483 new_event
.SetCurrentFocus( win
);
484 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
488 (gdk_event
->keyval
== GDK_Escape
) )
490 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
491 new_event
.SetEventObject( win
);
492 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
496 Damn, I forgot why this didn't work, but it didn't work.
498 // win is a panel: up can be propagated to the panel
499 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
500 (gdk_event->keyval == GDK_Up))
502 win->m_parent->SetFocus();
506 // win is a panel: left/right can be propagated to the panel
507 if ((!ret) && (win->m_wxwindow) &&
508 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
509 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
511 wxNavigationKeyEvent new_event;
512 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
513 new_event.SetCurrentFocus( win );
514 ret = win->GetEventHandler()->ProcessEvent( new_event );
520 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
527 //-----------------------------------------------------------------------------
528 // "key_release_event" from any window
529 //-----------------------------------------------------------------------------
531 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
534 wxapp_install_idle_handler();
536 if (!win
->m_hasVMT
) return FALSE
;
537 if (g_blockEventsOnDrag
) return FALSE
;
540 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
541 if (gdk_event->state & GDK_SHIFT_MASK)
542 printf( "ShiftDown.\n" );
544 printf( "ShiftUp.\n" );
545 if (gdk_event->state & GDK_CONTROL_MASK)
546 printf( "ControlDown.\n" );
548 printf( "ControlUp.\n" );
553 switch (gdk_event
->keyval
)
556 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
558 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
559 case GDK_Menu
: key_code
= WXK_MENU
; break;
560 case GDK_Help
: key_code
= WXK_HELP
; break;
561 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
562 case GDK_ISO_Left_Tab
:
564 case GDK_Tab
: key_code
= WXK_TAB
; break;
565 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
566 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
567 case GDK_Return
: key_code
= WXK_RETURN
; break;
568 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
569 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
570 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
571 case GDK_Delete
: key_code
= WXK_DELETE
; break;
572 case GDK_Home
: key_code
= WXK_HOME
; break;
573 case GDK_Left
: key_code
= WXK_LEFT
; break;
574 case GDK_Up
: key_code
= WXK_UP
; break;
575 case GDK_Right
: key_code
= WXK_RIGHT
; break;
576 case GDK_Down
: key_code
= WXK_DOWN
; break;
577 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
578 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
579 case GDK_Next
: key_code
= WXK_NEXT
; break;
580 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
581 case GDK_End
: key_code
= WXK_END
; break;
582 case GDK_Begin
: key_code
= WXK_HOME
; break;
583 case GDK_Select
: key_code
= WXK_SELECT
; break;
584 case GDK_Print
: key_code
= WXK_PRINT
; break;
585 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
586 case GDK_Insert
: key_code
= WXK_INSERT
; break;
587 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
588 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
589 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
590 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
591 case GDK_KP_Up
: key_code
= WXK_UP
; break;
592 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
593 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
594 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
595 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
596 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
597 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
598 case GDK_KP_End
: key_code
= WXK_END
; break;
599 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
600 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
601 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
602 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
603 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
604 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
605 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
606 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
607 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
608 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
609 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
610 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
611 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
612 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
613 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
614 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
615 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
616 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
617 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
618 case GDK_F1
: key_code
= WXK_F1
; break;
619 case GDK_F2
: key_code
= WXK_F2
; break;
620 case GDK_F3
: key_code
= WXK_F3
; break;
621 case GDK_F4
: key_code
= WXK_F4
; break;
622 case GDK_F5
: key_code
= WXK_F5
; break;
623 case GDK_F6
: key_code
= WXK_F6
; break;
624 case GDK_F7
: key_code
= WXK_F7
; break;
625 case GDK_F8
: key_code
= WXK_F8
; break;
626 case GDK_F9
: key_code
= WXK_F9
; break;
627 case GDK_F10
: key_code
= WXK_F10
; break;
628 case GDK_F11
: key_code
= WXK_F11
; break;
629 case GDK_F12
: key_code
= WXK_F12
; break;
632 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
633 key_code
= gdk_event
->keyval
;
639 GdkModifierType state
;
640 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
642 wxKeyEvent
event( wxEVT_KEY_UP
);
643 event
.SetTimestamp( gdk_event
->time
);
644 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
645 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
646 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
647 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
648 event
.m_keyCode
= key_code
;
649 event
.m_scanCode
= gdk_event
->keyval
;
652 event
.SetEventObject( win
);
654 if (win
->GetEventHandler()->ProcessEvent( event
))
656 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
663 //-----------------------------------------------------------------------------
664 // "button_press_event"
665 //-----------------------------------------------------------------------------
667 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
670 wxapp_install_idle_handler();
673 wxPrintf( _T("1) OnButtonPress from ") );
674 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
675 wxPrintf( win->GetClassInfo()->GetClassName() );
676 wxPrintf( _T(".\n") );
678 if (!win
->m_hasVMT
) return FALSE
;
679 if (g_blockEventsOnDrag
) return TRUE
;
680 if (g_blockEventsOnScroll
) return TRUE
;
682 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
686 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
688 gtk_widget_grab_focus (win
->m_wxwindow
);
691 wxPrintf( _T("GrabFocus from ") );
692 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
693 wxPrintf( win->GetClassInfo()->GetClassName() );
694 wxPrintf( _T(".\n") );
701 wxPrintf( _T("2) OnButtonPress from ") );
702 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
703 wxPrintf( win->GetClassInfo()->GetClassName() );
704 wxPrintf( _T(".\n") );
707 wxEventType event_type
= wxEVT_LEFT_DOWN
;
709 if (gdk_event
->button
== 1)
711 switch (gdk_event
->type
)
713 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
714 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
718 else if (gdk_event
->button
== 2)
720 switch (gdk_event
->type
)
722 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
723 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
727 else if (gdk_event
->button
== 3)
729 switch (gdk_event
->type
)
731 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
732 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
737 wxMouseEvent
event( event_type
);
738 event
.SetTimestamp( gdk_event
->time
);
739 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
740 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
741 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
742 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
743 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
744 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
745 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
747 event
.m_x
= (long)gdk_event
->x
;
748 event
.m_y
= (long)gdk_event
->y
;
750 // Some control don't have their own X window and thus cannot get
755 wxNode
*node
= win
->GetChildren().First();
758 wxWindow
*child
= (wxWindow
*)node
->Data();
760 if (child
->m_isStaticBox
)
762 // wxStaticBox is transparent in the box itself
765 int xx1
= child
->m_x
;
766 int yy1
= child
->m_y
;
767 int xx2
= child
->m_x
+ child
->m_width
;
768 int yy2
= child
->m_x
+ child
->m_height
;
771 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
773 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
775 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
777 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
780 event
.m_x
-= child
->m_x
;
781 event
.m_y
-= child
->m_y
;
788 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
789 (child
->m_x
<= event
.m_x
) &&
790 (child
->m_y
<= event
.m_y
) &&
791 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
792 (child
->m_y
+child
->m_height
>= event
.m_y
))
795 event
.m_x
-= child
->m_x
;
796 event
.m_y
-= child
->m_y
;
804 event
.SetEventObject( win
);
806 gs_timeLastClick
= gdk_event
->time
;
808 if (win
->GetEventHandler()->ProcessEvent( event
))
810 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
817 //-----------------------------------------------------------------------------
818 // "button_release_event"
819 //-----------------------------------------------------------------------------
821 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
824 wxapp_install_idle_handler();
826 if (!win
->m_hasVMT
) return FALSE
;
827 if (g_blockEventsOnDrag
) return FALSE
;
828 if (g_blockEventsOnScroll
) return FALSE
;
830 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
833 printf( "OnButtonRelease from " );
834 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
835 printf( win->GetClassInfo()->GetClassName() );
839 wxEventType event_type
= wxEVT_NULL
;
841 switch (gdk_event
->button
)
843 case 1: event_type
= wxEVT_LEFT_UP
; break;
844 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
845 case 3: event_type
= wxEVT_RIGHT_UP
; break;
848 wxMouseEvent
event( event_type
);
849 event
.SetTimestamp( gdk_event
->time
);
850 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
851 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
852 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
853 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
854 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
855 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
856 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
857 event
.m_x
= (long)gdk_event
->x
;
858 event
.m_y
= (long)gdk_event
->y
;
860 // Some control don't have their own X window and thus cannot get
865 wxNode
*node
= win
->GetChildren().First();
868 wxWindow
*child
= (wxWindow
*)node
->Data();
870 if (child
->m_isStaticBox
)
872 // wxStaticBox is transparent in the box itself
875 int xx1
= child
->m_x
;
876 int yy1
= child
->m_y
;
877 int xx2
= child
->m_x
+ child
->m_width
;
878 int yy2
= child
->m_x
+ child
->m_height
;
881 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
883 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
885 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
887 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
890 event
.m_x
-= child
->m_x
;
891 event
.m_y
-= child
->m_y
;
898 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
899 (child
->m_x
<= event
.m_x
) &&
900 (child
->m_y
<= event
.m_y
) &&
901 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
902 (child
->m_y
+child
->m_height
>= event
.m_y
))
905 event
.m_x
-= child
->m_x
;
906 event
.m_y
-= child
->m_y
;
914 event
.SetEventObject( win
);
916 if (win
->GetEventHandler()->ProcessEvent( event
))
918 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
925 //-----------------------------------------------------------------------------
926 // "motion_notify_event"
927 //-----------------------------------------------------------------------------
929 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
932 wxapp_install_idle_handler();
934 if (!win
->m_hasVMT
) return FALSE
;
935 if (g_blockEventsOnDrag
) return FALSE
;
936 if (g_blockEventsOnScroll
) return FALSE
;
938 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
940 if (gdk_event
->is_hint
)
944 GdkModifierType state
;
945 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
948 gdk_event
->state
= state
;
952 printf( "OnMotion from " );
953 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
954 printf( win->GetClassInfo()->GetClassName() );
958 wxMouseEvent
event( wxEVT_MOTION
);
959 event
.SetTimestamp( gdk_event
->time
);
960 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
961 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
962 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
963 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
964 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
965 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
966 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
968 event
.m_x
= (long)gdk_event
->x
;
969 event
.m_y
= (long)gdk_event
->y
;
971 // Some control don't have their own X window and thus cannot get
976 wxNode
*node
= win
->GetChildren().First();
979 wxWindow
*child
= (wxWindow
*)node
->Data();
981 if (child
->m_isStaticBox
)
983 // wxStaticBox is transparent in the box itself
986 int xx1
= child
->m_x
;
987 int yy1
= child
->m_y
;
988 int xx2
= child
->m_x
+ child
->m_width
;
989 int yy2
= child
->m_x
+ child
->m_height
;
992 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
994 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
996 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
998 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1001 event
.m_x
-= child
->m_x
;
1002 event
.m_y
-= child
->m_y
;
1009 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1010 (child
->m_x
<= event
.m_x
) &&
1011 (child
->m_y
<= event
.m_y
) &&
1012 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1013 (child
->m_y
+child
->m_height
>= event
.m_y
))
1016 event
.m_x
-= child
->m_x
;
1017 event
.m_y
-= child
->m_y
;
1021 node
= node
->Next();
1025 event
.SetEventObject( win
);
1027 if (win
->GetEventHandler()->ProcessEvent( event
))
1029 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1036 //-----------------------------------------------------------------------------
1038 //-----------------------------------------------------------------------------
1040 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1043 wxapp_install_idle_handler();
1045 if (!win
->m_hasVMT
) return FALSE
;
1046 if (g_blockEventsOnDrag
) return FALSE
;
1048 g_focusWindow
= win
;
1050 if (win
->m_wxwindow
)
1052 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1054 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1056 printf( "SetFocus flag from " );
1057 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1058 printf( win->GetClassInfo()->GetClassName() );
1066 printf( "OnSetFocus from " );
1067 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1068 printf( win->GetClassInfo()->GetClassName() );
1070 printf( WXSTRINGCAST win->GetLabel() );
1074 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1075 event
.SetEventObject( win
);
1077 if (win
->GetEventHandler()->ProcessEvent( event
))
1079 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1086 //-----------------------------------------------------------------------------
1087 // "focus_out_event"
1088 //-----------------------------------------------------------------------------
1090 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1093 wxapp_install_idle_handler();
1095 if (!win
->m_hasVMT
) return FALSE
;
1096 if (g_blockEventsOnDrag
) return FALSE
;
1098 if (win
->m_wxwindow
)
1100 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1101 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1105 printf( "OnKillFocus from " );
1106 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1107 printf( win->GetClassInfo()->GetClassName() );
1111 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1112 event
.SetEventObject( win
);
1114 if (win
->GetEventHandler()->ProcessEvent( event
))
1116 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1123 //-----------------------------------------------------------------------------
1124 // "enter_notify_event"
1125 //-----------------------------------------------------------------------------
1127 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1130 wxapp_install_idle_handler();
1132 if (!win
->m_hasVMT
) return FALSE
;
1133 if (g_blockEventsOnDrag
) return FALSE
;
1135 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1137 if (widget
->window
&& win
->GetCursor().Ok() )
1138 gdk_window_set_cursor( widget
->window
, win
->GetCursor().GetCursor() );
1140 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1141 event
.SetTimestamp( gdk_event
->time
);
1142 event
.SetEventObject( win
);
1146 GdkModifierType state
= (GdkModifierType
)0;
1148 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1150 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1151 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1152 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1153 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1154 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1155 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1156 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1158 event
.m_x
= (long)x
;
1159 event
.m_y
= (long)y
;
1161 if (win
->GetEventHandler()->ProcessEvent( event
))
1163 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1170 //-----------------------------------------------------------------------------
1171 // "leave_notify_event"
1172 //-----------------------------------------------------------------------------
1174 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1177 wxapp_install_idle_handler();
1179 if (!win
->m_hasVMT
) return FALSE
;
1180 if (g_blockEventsOnDrag
) return FALSE
;
1182 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1184 if (widget
->window
&& win
->GetCursor().Ok() )
1185 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1187 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1188 event
.SetTimestamp( gdk_event
->time
);
1189 event
.SetEventObject( win
);
1193 GdkModifierType state
= (GdkModifierType
)0;
1195 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1197 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1198 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1199 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1200 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1201 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1202 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1203 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1205 event
.m_x
= (long)x
;
1206 event
.m_y
= (long)y
;
1208 if (win
->GetEventHandler()->ProcessEvent( event
))
1210 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1217 //-----------------------------------------------------------------------------
1218 // "value_changed" from m_vAdjust
1219 //-----------------------------------------------------------------------------
1221 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1224 wxapp_install_idle_handler();
1226 if (g_blockEventsOnDrag
) return;
1228 if (!win
->m_hasVMT
) return;
1230 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1231 if (fabs(diff
) < 0.2) return;
1232 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1234 wxEventType command
= wxEVT_NULL
;
1236 float line_step
= win
->m_vAdjust
->step_increment
;
1237 float page_step
= win
->m_vAdjust
->page_increment
;
1239 if (win
->IsScrolling())
1241 command
= wxEVT_SCROLL_THUMBTRACK
;
1245 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1246 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1247 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1248 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1249 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1250 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1251 else command
= wxEVT_SCROLL_THUMBTRACK
;
1254 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1256 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1257 event
.SetEventObject( win
);
1258 win
->GetEventHandler()->ProcessEvent( event
);
1261 //-----------------------------------------------------------------------------
1262 // "value_changed" from m_hAdjust
1263 //-----------------------------------------------------------------------------
1265 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1268 wxapp_install_idle_handler();
1270 if (g_blockEventsOnDrag
) return;
1271 if (!win
->m_hasVMT
) return;
1273 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1274 if (fabs(diff
) < 0.2) return;
1275 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1277 wxEventType command
= wxEVT_NULL
;
1279 float line_step
= win
->m_hAdjust
->step_increment
;
1280 float page_step
= win
->m_hAdjust
->page_increment
;
1282 if (win
->IsScrolling())
1284 command
= wxEVT_SCROLL_THUMBTRACK
;
1288 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1289 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1290 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1291 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1292 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1293 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1294 else command
= wxEVT_SCROLL_THUMBTRACK
;
1297 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1299 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1300 event
.SetEventObject( win
);
1301 win
->GetEventHandler()->ProcessEvent( event
);
1304 //-----------------------------------------------------------------------------
1305 // "changed" from m_vAdjust
1306 //-----------------------------------------------------------------------------
1308 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1311 wxapp_install_idle_handler();
1313 if (g_blockEventsOnDrag
) return;
1314 if (!win
->m_hasVMT
) return;
1316 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1317 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1319 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1320 event
.SetEventObject( win
);
1321 win
->GetEventHandler()->ProcessEvent( event
);
1324 //-----------------------------------------------------------------------------
1325 // "changed" from m_hAdjust
1326 //-----------------------------------------------------------------------------
1328 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1331 wxapp_install_idle_handler();
1333 if (g_blockEventsOnDrag
) return;
1334 if (!win
->m_hasVMT
) return;
1336 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1337 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1339 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1340 event
.SetEventObject( win
);
1341 win
->GetEventHandler()->ProcessEvent( event
);
1344 //-----------------------------------------------------------------------------
1345 // "button_press_event" from scrollbar
1346 //-----------------------------------------------------------------------------
1348 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1349 GdkEventButton
*WXUNUSED(gdk_event
),
1353 wxapp_install_idle_handler();
1355 // don't test here as we can release the mouse while being over
1356 // a different window then the slider
1358 // if (gdk_event->window != widget->slider) return FALSE;
1360 win
->SetScrolling( TRUE
);
1365 //-----------------------------------------------------------------------------
1366 // "button_release_event" from scrollbar
1367 //-----------------------------------------------------------------------------
1369 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1370 GdkEventButton
*WXUNUSED(gdk_event
),
1374 // don't test here as we can release the mouse while being over
1375 // a different window then the slider
1377 // if (gdk_event->window != widget->slider) return FALSE;
1379 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1381 if (widget
== GTK_RANGE(scrolledWindow
->vscrollbar
))
1382 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1384 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1386 win
->SetScrolling( FALSE
);
1391 // ----------------------------------------------------------------------------
1392 // this wxWindowBase function is implemented here (in platform-specific file)
1393 // because it is static and so couldn't be made virtual
1394 // ----------------------------------------------------------------------------
1396 wxWindow
*wxWindowBase::FindFocus()
1398 return g_focusWindow
;
1401 //-----------------------------------------------------------------------------
1402 // "realize" from m_widget
1403 //-----------------------------------------------------------------------------
1405 /* we cannot set colours, fonts and cursors before the widget has
1406 been realized, so we do this directly after realization */
1409 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1412 wxapp_install_idle_handler();
1414 if (win
->m_delayedFont
)
1415 win
->SetFont( win
->GetFont() );
1417 if (win
->m_delayedBackgroundColour
)
1418 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1420 if (win
->m_delayedForegroundColour
)
1421 win
->SetForegroundColour( win
->GetForegroundColour() );
1423 win
->SetCursor( win
->GetCursor() );
1428 //-----------------------------------------------------------------------------
1429 // InsertChild for wxWindow.
1430 //-----------------------------------------------------------------------------
1432 /* Callback for wxWindow. This very strange beast has to be used because
1433 * C++ has no virtual methods in a constructor. We have to emulate a
1434 * virtual function here as wxNotebook requires a different way to insert
1435 * a child in it. I had opted for creating a wxNotebookPage window class
1436 * which would have made this superfluous (such in the MDI window system),
1437 * but no-one was listening to me... */
1439 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1441 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1442 GTK_WIDGET(child
->m_widget
),
1448 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1450 /* we now allow a window to get the focus as long as it
1451 doesn't have any children. */
1452 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1456 //-----------------------------------------------------------------------------
1458 //-----------------------------------------------------------------------------
1460 wxWindow
* wxGetActiveWindow()
1462 return g_focusWindow
;
1465 //-----------------------------------------------------------------------------
1467 //-----------------------------------------------------------------------------
1469 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1471 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
)
1472 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1475 void wxWindow::Init()
1481 m_widget
= (GtkWidget
*) NULL
;
1482 m_wxwindow
= (GtkWidget
*) NULL
;
1492 m_needParent
= TRUE
;
1493 m_isBeingDeleted
= FALSE
;
1495 m_hasScrolling
= FALSE
;
1496 m_isScrolling
= FALSE
;
1498 m_hAdjust
= (GtkAdjustment
*) NULL
;
1499 m_vAdjust
= (GtkAdjustment
*) NULL
;
1500 m_oldHorizontalPos
= 0.0;
1501 m_oldVerticalPos
= 0.0;
1504 m_scrollGC
= (GdkGC
*) NULL
;
1505 m_widgetStyle
= (GtkStyle
*) NULL
;
1507 m_insertCallback
= wxInsertChildInWindow
;
1509 m_isStaticBox
= FALSE
;
1510 m_acceptsFocus
= FALSE
;
1513 wxWindow::wxWindow()
1518 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1519 const wxPoint
&pos
, const wxSize
&size
,
1520 long style
, const wxString
&name
)
1524 Create( parent
, id
, pos
, size
, style
, name
);
1527 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1528 const wxPoint
&pos
, const wxSize
&size
,
1529 long style
, const wxString
&name
)
1531 PreCreation( parent
, id
, pos
, size
, style
, name
);
1533 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1534 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1537 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1540 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1543 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1544 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1547 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1548 scroll_class
->scrollbar_spacing
= 0;
1550 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1552 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1553 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1555 m_wxwindow
= gtk_myfixed_new();
1558 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1561 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1563 #if (GTK_MINOR_VERSION > 0)
1564 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1566 if (HasFlag(wxRAISED_BORDER
))
1568 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1570 else if (HasFlag(wxSUNKEN_BORDER
))
1572 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1576 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1578 #else // GTK_MINOR_VERSION == 0
1579 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1581 if (HasFlag(wxRAISED_BORDER
))
1583 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1585 else if (HasFlag(wxSUNKEN_BORDER
))
1587 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1591 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1593 #endif // GTK_MINOR_VERSION
1595 if (HasFlag(wxTAB_TRAVERSAL
))
1597 /* we now allow a window to get the focus as long as it
1598 doesn't have any children. */
1599 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1600 m_acceptsFocus
= FALSE
;
1604 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1605 m_acceptsFocus
= TRUE
;
1608 #if (GTK_MINOR_VERSION == 0)
1609 // shut the viewport up
1610 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1611 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1612 #endif // GTK_MINOR_VERSION == 0
1614 // I _really_ don't want scrollbars in the beginning
1615 m_vAdjust
->lower
= 0.0;
1616 m_vAdjust
->upper
= 1.0;
1617 m_vAdjust
->value
= 0.0;
1618 m_vAdjust
->step_increment
= 1.0;
1619 m_vAdjust
->page_increment
= 1.0;
1620 m_vAdjust
->page_size
= 5.0;
1621 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1622 m_hAdjust
->lower
= 0.0;
1623 m_hAdjust
->upper
= 1.0;
1624 m_hAdjust
->value
= 0.0;
1625 m_hAdjust
->step_increment
= 1.0;
1626 m_hAdjust
->page_increment
= 1.0;
1627 m_hAdjust
->page_size
= 5.0;
1628 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1630 // these handlers block mouse events to any window during scrolling such as
1631 // motion events and prevent GTK and wxWindows from fighting over where the
1634 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1635 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1637 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1638 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1640 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1641 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1643 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1644 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1646 // these handlers get notified when screen updates are required either when
1647 // scrolling or when the window size (and therefore scrollbar configuration)
1650 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1651 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1652 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1653 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1655 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1656 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1657 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1658 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1660 gtk_widget_show( m_wxwindow
);
1663 m_parent
->DoAddChild( this );
1672 wxWindow::~wxWindow()
1674 m_isBeingDeleted
= TRUE
;
1683 m_parent
->RemoveChild( this );
1687 gtk_style_unref( m_widgetStyle
);
1688 m_widgetStyle
= (GtkStyle
*) NULL
;
1693 gdk_gc_unref( m_scrollGC
);
1694 m_scrollGC
= (GdkGC
*) NULL
;
1699 gtk_widget_destroy( m_wxwindow
);
1700 m_wxwindow
= (GtkWidget
*) NULL
;
1705 gtk_widget_destroy( m_widget
);
1706 m_widget
= (GtkWidget
*) NULL
;
1710 void wxWindow::PreCreation( wxWindow
*parent
,
1715 const wxString
&name
)
1717 wxASSERT_MSG( !m_needParent
|| parent
, _T("Need complete parent.") );
1719 if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) )
1721 wxFAIL_MSG(_T("window creation failed"));
1724 m_width
= WidthDefault(size
.x
);
1725 m_height
= HeightDefault(size
.y
);
1730 if (!parent
) /* some reasonable defaults */
1734 m_x
= (gdk_screen_width () - m_width
) / 2;
1735 if (m_x
< 10) m_x
= 10;
1739 m_y
= (gdk_screen_height () - m_height
) / 2;
1740 if (m_y
< 10) m_y
= 10;
1745 void wxWindow::PostCreation()
1747 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1751 /* these get reported to wxWindows -> wxPaintEvent */
1752 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1753 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1755 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1756 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1758 #if (GTK_MINOR_VERSION > 0)
1759 /* these are called when the "sunken" or "raised" borders are drawn */
1760 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1761 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1763 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1764 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1768 GtkWidget
*connect_widget
= GetConnectWidget();
1770 ConnectWidget( connect_widget
);
1772 /* we cannot set colours, fonts and cursors before the widget has
1773 been realized, so we do this directly after realization */
1774 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1775 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1780 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1782 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1783 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1785 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1786 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1788 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1789 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1791 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1792 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1794 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1795 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1797 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1798 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1800 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1801 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1803 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1804 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1806 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1807 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1810 bool wxWindow::Destroy()
1812 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1816 return wxWindowBase::Destroy();
1819 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1821 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1822 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1824 if (m_resizing
) return; /* I don't like recursions */
1827 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1829 /* don't set the size for children of wxNotebook, just take the values. */
1837 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1839 if (x
!= -1) m_x
= x
;
1840 if (y
!= -1) m_y
= y
;
1841 if (width
!= -1) m_width
= width
;
1842 if (height
!= -1) m_height
= height
;
1852 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1854 if (width
== -1) m_width
= 80;
1857 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1859 if (height
== -1) m_height
= 26;
1862 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1863 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1864 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1865 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1869 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1871 /* the default button has a border around it */
1875 /* this is the result of hours of debugging: the following code
1876 means that if we have a m_wxwindow and we set the size of
1877 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
1878 automatically propagate its size down to its m_wxwindow,
1879 which is its client area. therefore, we have to tell the
1880 client area directly that it has to resize itself.
1881 this will lead to that m_widget (GtkScrolledWindow) will
1882 calculate how much size it needs for scrollbars etc and
1883 it will then call XXX_size_allocate of its child, which
1884 is m_wxwindow. m_wxwindow in turn will do the same with its
1885 children and so on. problems can arise if this happens
1886 before all the children have been realized as some widgets
1887 stupidy need to be realized during XXX_size_allocate (e.g.
1888 GtkNotebook) and they will segv if called otherwise. this
1889 emergency is tested in gtk_myfixed_size_allocate. Normally
1890 this shouldn't be needed and only gtk_widget_queue_resize()
1891 should be enough to provoke a resize at the next appropriate
1892 moment, but this seems to fail, e.g. when a wxNotebook contains
1893 a wxSplitterWindow: the splitter window's children won't
1894 show up properly resized then. */
1896 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
1901 m_height
+2*border
);
1906 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1907 event
.SetEventObject( this );
1908 GetEventHandler()->ProcessEvent( event
);
1913 void wxWindow::OnInternalIdle()
1918 void wxWindow::DoGetSize( int *width
, int *height
) const
1920 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1922 if (width
) (*width
) = m_width
;
1923 if (height
) (*height
) = m_height
;
1926 void wxWindow::DoSetClientSize( int width
, int height
)
1928 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1932 SetSize( width
, height
);
1939 if (!m_hasScrolling
)
1941 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1943 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1945 dw
+= 2 * window_class
->xthickness
;
1946 dh
+= 2 * window_class
->ythickness
;
1951 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1952 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1954 #if (GTK_MINOR_VERSION == 0)
1955 GtkWidget
*viewport
= scroll_window
->viewport
;
1956 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1958 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1960 dw
+= 2 * viewport_class
->xthickness
;
1961 dh
+= 2 * viewport_class
->ythickness
;
1966 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1967 GtkWidget *vscrollbar = scroll_window->vscrollbar;
1969 we use this instead: range.slider_width = 11 + 2*2pts edge
1972 if (scroll_window
->vscrollbar_visible
)
1974 dw
+= 15; /* dw += vscrollbar->allocation.width; */
1975 dw
+= scroll_class
->scrollbar_spacing
;
1978 if (scroll_window
->hscrollbar_visible
)
1980 dh
+= 15; /* dh += hscrollbar->allocation.height; */
1981 dw
+= scroll_class
->scrollbar_spacing
;
1985 SetSize( width
+dw
, height
+dh
);
1989 void wxWindow::DoGetClientSize( int *width
, int *height
) const
1991 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1995 if (width
) (*width
) = m_width
;
1996 if (height
) (*height
) = m_height
;
2003 if (!m_hasScrolling
)
2005 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2007 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2009 dw
+= 2 * window_class
->xthickness
;
2010 dh
+= 2 * window_class
->ythickness
;
2015 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2016 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2018 #if (GTK_MINOR_VERSION == 0)
2019 GtkWidget
*viewport
= scroll_window
->viewport
;
2020 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2022 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) )
2024 dw
+= 2 * viewport_class
->xthickness
;
2025 dh
+= 2 * viewport_class
->ythickness
;
2029 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2030 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2032 we use this instead: range.slider_width = 11 + 2*2pts edge
2035 if (scroll_window
->vscrollbar_visible
)
2037 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2038 dw
+= scroll_class
->scrollbar_spacing
;
2041 if (scroll_window
->hscrollbar_visible
)
2043 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2044 dh
+= scroll_class
->scrollbar_spacing
;
2048 if (width
) (*width
) = m_width
- dw
;
2049 if (height
) (*height
) = m_height
- dh
;
2053 void wxWindow::DoGetPosition( int *x
, int *y
) const
2055 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2061 void wxWindow::ClientToScreen( int *x
, int *y
) const
2063 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2065 if (!m_widget
->window
) return;
2067 GdkWindow
*source
= (GdkWindow
*) NULL
;
2069 source
= m_wxwindow
->window
;
2071 source
= m_widget
->window
;
2075 gdk_window_get_origin( source
, &org_x
, &org_y
);
2079 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2081 org_x
+= m_widget
->allocation
.x
;
2082 org_y
+= m_widget
->allocation
.y
;
2090 void wxWindow::ScreenToClient( int *x
, int *y
) const
2092 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2094 if (!m_widget
->window
) return;
2096 GdkWindow
*source
= (GdkWindow
*) NULL
;
2098 source
= m_wxwindow
->window
;
2100 source
= m_widget
->window
;
2104 gdk_window_get_origin( source
, &org_x
, &org_y
);
2108 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2110 org_x
+= m_widget
->allocation
.x
;
2111 org_y
+= m_widget
->allocation
.y
;
2119 bool wxWindow::Show( bool show
)
2121 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2123 if (!wxWindowBase::Show(show
))
2130 gtk_widget_show( m_widget
);
2132 gtk_widget_hide( m_widget
);
2137 bool wxWindow::Enable( bool enable
)
2139 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2141 if (!wxWindowBase::Enable(enable
))
2147 gtk_widget_set_sensitive( m_widget
, enable
);
2149 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2154 int wxWindow::GetCharHeight() const
2156 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2158 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2160 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2162 return font
->ascent
+ font
->descent
;
2165 int wxWindow::GetCharWidth() const
2167 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2169 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2171 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2173 return gdk_string_width( font
, "H" );
2176 void wxWindow::GetTextExtent( const wxString
& string
,
2180 int *externalLeading
,
2181 const wxFont
*theFont
) const
2183 wxFont fontToUse
= m_font
;
2184 if (theFont
) fontToUse
= *theFont
;
2186 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2188 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2189 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2190 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2191 if (descent
) (*descent
) = font
->descent
;
2192 if (externalLeading
) (*externalLeading
) = 0; // ??
2195 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2197 event
.SetEventType( wxEVT_CHAR
);
2199 if (!GetEventHandler()->ProcessEvent( event
))
2205 void wxWindow::SetFocus()
2207 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2209 GtkWidget
*connect_widget
= GetConnectWidget();
2212 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2214 gtk_widget_grab_focus (connect_widget
);
2216 else if (GTK_IS_CONTAINER(connect_widget
))
2218 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2226 bool wxWindow::AcceptsFocus() const
2228 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2231 bool wxWindow::Reparent( wxWindow
*newParent
)
2233 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2235 gtk_widget_unparent( m_widget
);
2237 if ( !wxWindowBase::Reparent(newParent
) )
2243 void wxWindow::Raise()
2245 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2247 if (!m_widget
->window
) return;
2249 gdk_window_raise( m_widget
->window
);
2252 void wxWindow::Lower()
2254 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2256 if (!m_widget
->window
) return;
2258 gdk_window_lower( m_widget
->window
);
2261 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2263 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2265 if (!wxWindowBase::SetCursor(cursor
))
2267 // don't leave if the GTK widget has just
2269 if (!m_delayedCursor
) return FALSE
;
2272 GtkWidget
*connect_widget
= GetConnectWidget();
2273 if (!connect_widget
->window
)
2275 // indicate that a new style has been set
2276 // but it couldn't get applied as the
2277 // widget hasn't been realized yet.
2278 m_delayedCursor
= TRUE
;
2280 // pretend we have done something
2284 if ((m_widget
) && (m_widget
->window
))
2285 gdk_window_set_cursor( m_widget
->window
, GetCursor().GetCursor() );
2287 if ((m_wxwindow
) && (m_wxwindow
->window
))
2288 gdk_window_set_cursor( m_wxwindow
->window
, GetCursor().GetCursor() );
2294 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2299 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2301 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2303 if (!m_widget
->window
) return;
2305 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2309 gdk_window_clear_area( m_wxwindow
->window
,
2311 rect
->width
, rect
->height
);
2315 gdk_window_clear( m_wxwindow
->window
);
2322 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2324 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2328 GdkRectangle gdk_rect
;
2329 gdk_rect
.x
= rect
->x
;
2330 gdk_rect
.y
= rect
->y
;
2331 gdk_rect
.width
= rect
->width
;
2332 gdk_rect
.height
= rect
->height
;
2335 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2337 gtk_widget_draw( m_widget
, &gdk_rect
);
2341 void wxWindow::Clear()
2343 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2345 if (!m_widget
->window
) return;
2347 if (m_wxwindow
&& m_wxwindow
->window
)
2349 gdk_window_clear( m_wxwindow
->window
);
2354 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2356 wxWindowBase::DoSetToolTip(tip
);
2359 m_tooltip
->Apply( this );
2362 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2364 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2366 #endif // wxUSE_TOOLTIPS
2368 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2370 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2372 if (!wxWindowBase::SetBackgroundColour(colour
))
2374 // don't leave if the GTK widget has just
2376 if (!m_delayedBackgroundColour
) return FALSE
;
2379 GtkWidget
*connect_widget
= GetConnectWidget();
2380 if (!connect_widget
->window
)
2382 // indicate that a new style has been set
2383 // but it couldn't get applied as the
2384 // widget hasn't been realized yet.
2385 m_delayedBackgroundColour
= TRUE
;
2387 // pretend we have done something
2391 if (m_wxwindow
&& m_wxwindow
->window
)
2393 /* wxMSW doesn't clear the window here. I don't do that either to
2394 provide compatibility. call Clear() to do the job. */
2396 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2397 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2400 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2402 if (sysbg
== m_backgroundColour
)
2404 m_backgroundColour
= wxNullColour
;
2406 m_backgroundColour
= sysbg
;
2416 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2418 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2420 if (!wxWindowBase::SetForegroundColour(colour
))
2422 // don't leave if the GTK widget has just
2424 if (!m_delayedForegroundColour
) return FALSE
;
2427 GtkWidget
*connect_widget
= GetConnectWidget();
2428 if (!connect_widget
->window
)
2430 // indicate that a new style has been set
2431 // but it couldn't get applied as the
2432 // widget hasn't been realized yet.
2433 m_delayedForegroundColour
= TRUE
;
2435 // pretend we have done something
2439 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2440 if (sysbg
== m_foregroundColour
)
2442 m_backgroundColour
= wxNullColour
;
2444 m_backgroundColour
= sysbg
;
2454 GtkStyle
*wxWindow::GetWidgetStyle()
2456 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2458 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2460 return m_widgetStyle
;
2463 void wxWindow::SetWidgetStyle()
2465 GtkStyle
*style
= GetWidgetStyle();
2467 gdk_font_unref( style
->font
);
2468 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2470 if (m_foregroundColour
.Ok())
2472 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2473 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2474 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2475 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2478 if (m_backgroundColour
.Ok())
2480 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2481 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2482 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2483 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2484 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2485 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2486 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2487 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2488 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2492 void wxWindow::ApplyWidgetStyle()
2496 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2498 menu
->SetInvokingWindow( win
);
2499 wxNode
*node
= menu
->GetItems().First();
2502 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2503 if (menuitem
->IsSubMenu())
2505 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2507 node
= node
->Next();
2511 static gint gs_pop_x
= 0;
2512 static gint gs_pop_y
= 0;
2514 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2518 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2523 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2525 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2527 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2529 SetInvokingWindow( menu
, this );
2537 GTK_MENU(menu
->m_menu
),
2538 (GtkWidget
*) NULL
, // parent menu shell
2539 (GtkWidget
*) NULL
, // parent menu item
2540 (GtkMenuPositionFunc
) pop_pos_callback
,
2541 (gpointer
) this, // client data
2542 0, // button used to activate it
2543 0 //gs_timeLastClick // the time of activation
2548 #if wxUSE_DRAG_AND_DROP
2550 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2552 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2554 GtkWidget
*dnd_widget
= GetConnectWidget();
2556 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2558 if (m_dropTarget
) delete m_dropTarget
;
2559 m_dropTarget
= dropTarget
;
2561 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2564 #endif // wxUSE_DRAG_AND_DROP
2566 GtkWidget
* wxWindow::GetConnectWidget()
2568 GtkWidget
*connect_widget
= m_widget
;
2569 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2571 return connect_widget
;
2574 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2576 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2577 return (window
== m_widget
->window
);
2580 bool wxWindow::SetFont( const wxFont
&font
)
2582 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T( "invalid window") );
2584 if (!wxWindowBase::SetFont(font
))
2586 // don't leave if the GTK widget has just
2588 if (!m_delayedFont
) return FALSE
;
2591 GtkWidget
*connect_widget
= GetConnectWidget();
2592 if (!connect_widget
->window
)
2594 // indicate that a new style has been set
2595 // but it couldn't get applied as the
2596 // widget hasn't been realized yet.
2597 m_delayedFont
= TRUE
;
2599 // pretend we have done something
2603 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2604 if ( sysbg
== m_backgroundColour
)
2606 m_backgroundColour
= wxNullColour
;
2608 m_backgroundColour
= sysbg
;
2618 void wxWindow::CaptureMouse()
2620 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2622 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
2624 GtkWidget
*connect_widget
= GetConnectWidget();
2625 if (!connect_widget
->window
) return;
2627 gtk_grab_add( connect_widget
);
2628 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2630 (GDK_BUTTON_PRESS_MASK
|
2631 GDK_BUTTON_RELEASE_MASK
|
2632 GDK_POINTER_MOTION_MASK
),
2639 void wxWindow::ReleaseMouse()
2641 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2643 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
2645 GtkWidget
*connect_widget
= GetConnectWidget();
2646 if (!connect_widget
->window
) return;
2648 gtk_grab_remove( connect_widget
);
2649 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2650 g_capturing
= FALSE
;
2653 bool wxWindow::IsRetained() const
2658 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2659 int range
, bool refresh
)
2661 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2663 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2665 m_hasScrolling
= TRUE
;
2667 if (orient
== wxHORIZONTAL
)
2669 float fpos
= (float)pos
;
2670 float frange
= (float)range
;
2671 float fthumb
= (float)thumbVisible
;
2672 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2673 if (fpos
< 0.0) fpos
= 0.0;
2675 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2676 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2678 SetScrollPos( orient
, pos
, refresh
);
2682 m_oldHorizontalPos
= fpos
;
2684 m_hAdjust
->lower
= 0.0;
2685 m_hAdjust
->upper
= frange
;
2686 m_hAdjust
->value
= fpos
;
2687 m_hAdjust
->step_increment
= 1.0;
2688 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2689 m_hAdjust
->page_size
= fthumb
;
2693 float fpos
= (float)pos
;
2694 float frange
= (float)range
;
2695 float fthumb
= (float)thumbVisible
;
2696 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2697 if (fpos
< 0.0) fpos
= 0.0;
2699 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2700 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2702 SetScrollPos( orient
, pos
, refresh
);
2706 m_oldVerticalPos
= fpos
;
2708 m_vAdjust
->lower
= 0.0;
2709 m_vAdjust
->upper
= frange
;
2710 m_vAdjust
->value
= fpos
;
2711 m_vAdjust
->step_increment
= 1.0;
2712 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2713 m_vAdjust
->page_size
= fthumb
;
2716 if (orient
== wxHORIZONTAL
)
2717 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2719 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2722 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2724 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2726 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2728 if (orient
== wxHORIZONTAL
)
2730 float fpos
= (float)pos
;
2731 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2732 if (fpos
< 0.0) fpos
= 0.0;
2733 m_oldHorizontalPos
= fpos
;
2735 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2736 m_hAdjust
->value
= fpos
;
2740 float fpos
= (float)pos
;
2741 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2742 if (fpos
< 0.0) fpos
= 0.0;
2743 m_oldVerticalPos
= fpos
;
2745 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2746 m_vAdjust
->value
= fpos
;
2749 if (!m_isScrolling
) /* prevent recursion */
2751 if (m_wxwindow
->window
)
2753 if (orient
== wxHORIZONTAL
)
2754 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2756 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2761 int wxWindow::GetScrollThumb( int orient
) const
2763 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2765 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2767 if (orient
== wxHORIZONTAL
)
2768 return (int)(m_hAdjust
->page_size
+0.5);
2770 return (int)(m_vAdjust
->page_size
+0.5);
2773 int wxWindow::GetScrollPos( int orient
) const
2775 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2777 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2779 if (orient
== wxHORIZONTAL
)
2780 return (int)(m_hAdjust
->value
+0.5);
2782 return (int)(m_vAdjust
->value
+0.5);
2785 int wxWindow::GetScrollRange( int orient
) const
2787 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2789 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2791 if (orient
== wxHORIZONTAL
)
2792 return (int)(m_hAdjust
->upper
+0.5);
2794 return (int)(m_vAdjust
->upper
+0.5);
2797 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2799 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2801 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2805 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2806 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2811 GetClientSize( &cw
, &ch
);
2812 int w
= cw
- abs(dx
);
2813 int h
= ch
- abs(dy
);
2815 if ((h
< 0) || (w
< 0))
2823 if (dx
< 0) s_x
= -dx
;
2824 if (dy
< 0) s_y
= -dy
;
2827 if (dx
> 0) d_x
= dx
;
2828 if (dy
> 0) d_y
= dy
;
2830 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2831 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2834 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2835 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2836 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2837 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2839 Refresh( TRUE
, &rect
);
2842 wxNode
*node
= m_children
.First();
2845 wxWindow
*child
= (wxWindow
*) node
->Data();
2846 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
2847 node
= node
->Next();
2851 void wxWindow::SetScrolling(bool scroll
)
2853 m_isScrolling
= g_blockEventsOnScroll
= scroll
;