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
)
356 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
357 case GDK_ISO_Left_Tab
:
359 case GDK_Tab
: key_code
= WXK_TAB
; break;
360 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
361 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
362 case GDK_Return
: key_code
= WXK_RETURN
; break;
363 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
364 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
365 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
366 case GDK_Delete
: key_code
= WXK_DELETE
; break;
367 case GDK_Home
: key_code
= WXK_HOME
; break;
368 case GDK_Left
: key_code
= WXK_LEFT
; break;
369 case GDK_Up
: key_code
= WXK_UP
; break;
370 case GDK_Right
: key_code
= WXK_RIGHT
; break;
371 case GDK_Down
: key_code
= WXK_DOWN
; break;
372 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
373 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
374 case GDK_Next
: key_code
= WXK_NEXT
; break;
375 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
376 case GDK_End
: key_code
= WXK_END
; break;
377 case GDK_Begin
: key_code
= WXK_HOME
; break;
378 case GDK_Select
: key_code
= WXK_SELECT
; break;
379 case GDK_Print
: key_code
= WXK_PRINT
; break;
380 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
381 case GDK_Insert
: key_code
= WXK_INSERT
; break;
382 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
383 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
384 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
385 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
386 case GDK_KP_Up
: key_code
= WXK_UP
; break;
387 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
388 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
389 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
390 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
391 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
392 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
393 case GDK_KP_End
: key_code
= WXK_END
; break;
394 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
395 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
396 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
397 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
398 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
399 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
400 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
401 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
402 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
403 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
404 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
405 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
406 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
407 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
408 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
409 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
410 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
411 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
412 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
413 case GDK_F1
: key_code
= WXK_F1
; break;
414 case GDK_F2
: key_code
= WXK_F2
; break;
415 case GDK_F3
: key_code
= WXK_F3
; break;
416 case GDK_F4
: key_code
= WXK_F4
; break;
417 case GDK_F5
: key_code
= WXK_F5
; break;
418 case GDK_F6
: key_code
= WXK_F6
; break;
419 case GDK_F7
: key_code
= WXK_F7
; break;
420 case GDK_F8
: key_code
= WXK_F8
; break;
421 case GDK_F9
: key_code
= WXK_F9
; break;
422 case GDK_F10
: key_code
= WXK_F10
; break;
423 case GDK_F11
: key_code
= WXK_F11
; break;
424 case GDK_F12
: key_code
= WXK_F12
; break;
427 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
428 key_code
= gdk_event
->keyval
;
432 if (!key_code
) return FALSE
;
434 wxKeyEvent
event( wxEVT_KEY_DOWN
);
435 event
.SetTimestamp( gdk_event
->time
);
436 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
437 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
438 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
439 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
440 event
.m_keyCode
= key_code
;
443 event
.SetEventObject( win
);
445 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
449 wxWindow
*ancestor
= win
;
452 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
455 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
456 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
459 ancestor
= ancestor
->GetParent();
463 // win is a control: tab can be propagated up
465 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
466 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
468 wxNavigationKeyEvent new_event
;
469 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
470 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
471 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
472 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
473 new_event
.SetCurrentFocus( win
);
474 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
478 (gdk_event
->keyval
== GDK_Escape
) )
480 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
481 new_event
.SetEventObject( win
);
482 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
486 Damn, I forgot why this didn't work, but it didn't work.
488 // win is a panel: up can be propagated to the panel
489 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
490 (gdk_event->keyval == GDK_Up))
492 win->m_parent->SetFocus();
496 // win is a panel: left/right can be propagated to the panel
497 if ((!ret) && (win->m_wxwindow) &&
498 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
499 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
501 wxNavigationKeyEvent new_event;
502 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
503 new_event.SetCurrentFocus( win );
504 ret = win->GetEventHandler()->ProcessEvent( new_event );
510 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
517 //-----------------------------------------------------------------------------
518 // "key_release_event" from any window
519 //-----------------------------------------------------------------------------
521 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
524 wxapp_install_idle_handler();
526 if (!win
->m_hasVMT
) return FALSE
;
527 if (g_blockEventsOnDrag
) return FALSE
;
530 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
531 if (gdk_event->state & GDK_SHIFT_MASK)
532 printf( "ShiftDown.\n" );
534 printf( "ShiftUp.\n" );
535 if (gdk_event->state & GDK_CONTROL_MASK)
536 printf( "ControlDown.\n" );
538 printf( "ControlUp.\n" );
543 switch (gdk_event
->keyval
)
545 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
546 case GDK_ISO_Left_Tab
:
548 case GDK_Tab
: key_code
= WXK_TAB
; break;
549 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
550 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
551 case GDK_Return
: key_code
= WXK_RETURN
; break;
552 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
553 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
554 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
555 case GDK_Delete
: key_code
= WXK_DELETE
; break;
556 case GDK_Home
: key_code
= WXK_HOME
; break;
557 case GDK_Left
: key_code
= WXK_LEFT
; break;
558 case GDK_Up
: key_code
= WXK_UP
; break;
559 case GDK_Right
: key_code
= WXK_RIGHT
; break;
560 case GDK_Down
: key_code
= WXK_DOWN
; break;
561 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
562 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
563 case GDK_Next
: key_code
= WXK_NEXT
; break;
564 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
565 case GDK_End
: key_code
= WXK_END
; break;
566 case GDK_Begin
: key_code
= WXK_HOME
; break;
567 case GDK_Select
: key_code
= WXK_SELECT
; break;
568 case GDK_Print
: key_code
= WXK_PRINT
; break;
569 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
570 case GDK_Insert
: key_code
= WXK_INSERT
; break;
571 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
572 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
573 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
574 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
575 case GDK_KP_Up
: key_code
= WXK_UP
; break;
576 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
577 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
578 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
579 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
580 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
581 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
582 case GDK_KP_End
: key_code
= WXK_END
; break;
583 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
584 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
585 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
586 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
587 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
588 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
589 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
590 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
591 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
592 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
593 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
594 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
595 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
596 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
597 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
598 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
599 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
600 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
601 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
602 case GDK_F1
: key_code
= WXK_F1
; break;
603 case GDK_F2
: key_code
= WXK_F2
; break;
604 case GDK_F3
: key_code
= WXK_F3
; break;
605 case GDK_F4
: key_code
= WXK_F4
; break;
606 case GDK_F5
: key_code
= WXK_F5
; break;
607 case GDK_F6
: key_code
= WXK_F6
; break;
608 case GDK_F7
: key_code
= WXK_F7
; break;
609 case GDK_F8
: key_code
= WXK_F8
; break;
610 case GDK_F9
: key_code
= WXK_F9
; break;
611 case GDK_F10
: key_code
= WXK_F10
; break;
612 case GDK_F11
: key_code
= WXK_F11
; break;
613 case GDK_F12
: key_code
= WXK_F12
; break;
616 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
617 key_code
= gdk_event
->keyval
;
621 if (!key_code
) return FALSE
;
623 wxKeyEvent
event( wxEVT_KEY_UP
);
624 event
.SetTimestamp( gdk_event
->time
);
625 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
626 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
627 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
628 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
629 event
.m_keyCode
= key_code
;
632 event
.SetEventObject( win
);
634 if (win
->GetEventHandler()->ProcessEvent( event
))
636 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
643 //-----------------------------------------------------------------------------
644 // "button_press_event"
645 //-----------------------------------------------------------------------------
647 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
650 wxapp_install_idle_handler();
653 wxPrintf( _T("1) OnButtonPress from ") );
654 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
655 wxPrintf( win->GetClassInfo()->GetClassName() );
656 wxPrintf( _T(".\n") );
658 if (!win
->m_hasVMT
) return FALSE
;
659 if (g_blockEventsOnDrag
) return TRUE
;
660 if (g_blockEventsOnScroll
) return TRUE
;
662 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
666 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
668 gtk_widget_grab_focus (win
->m_wxwindow
);
671 wxPrintf( _T("GrabFocus from ") );
672 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
673 wxPrintf( win->GetClassInfo()->GetClassName() );
674 wxPrintf( _T(".\n") );
681 wxPrintf( _T("2) OnButtonPress from ") );
682 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
683 wxPrintf( win->GetClassInfo()->GetClassName() );
684 wxPrintf( _T(".\n") );
687 wxEventType event_type
= wxEVT_LEFT_DOWN
;
689 if (gdk_event
->button
== 1)
691 switch (gdk_event
->type
)
693 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
694 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
698 else if (gdk_event
->button
== 2)
700 switch (gdk_event
->type
)
702 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
703 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
707 else if (gdk_event
->button
== 3)
709 switch (gdk_event
->type
)
711 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
712 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
717 wxMouseEvent
event( event_type
);
718 event
.SetTimestamp( gdk_event
->time
);
719 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
720 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
721 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
722 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
723 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
724 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
725 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
727 event
.m_x
= (long)gdk_event
->x
;
728 event
.m_y
= (long)gdk_event
->y
;
730 // Some control don't have their own X window and thus cannot get
735 wxNode
*node
= win
->GetChildren().First();
738 wxWindow
*child
= (wxWindow
*)node
->Data();
740 if (child
->m_isStaticBox
)
742 // wxStaticBox is transparent in the box itself
745 int xx1
= child
->m_x
;
746 int yy1
= child
->m_y
;
747 int xx2
= child
->m_x
+ child
->m_width
;
748 int yy2
= child
->m_x
+ child
->m_height
;
751 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
753 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
755 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
757 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
760 event
.m_x
-= child
->m_x
;
761 event
.m_y
-= child
->m_y
;
768 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
769 (child
->m_x
<= event
.m_x
) &&
770 (child
->m_y
<= event
.m_y
) &&
771 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
772 (child
->m_y
+child
->m_height
>= event
.m_y
))
775 event
.m_x
-= child
->m_x
;
776 event
.m_y
-= child
->m_y
;
784 event
.SetEventObject( win
);
786 gs_timeLastClick
= gdk_event
->time
;
788 if (win
->GetEventHandler()->ProcessEvent( event
))
790 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
797 //-----------------------------------------------------------------------------
798 // "button_release_event"
799 //-----------------------------------------------------------------------------
801 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
804 wxapp_install_idle_handler();
806 if (!win
->m_hasVMT
) return FALSE
;
807 if (g_blockEventsOnDrag
) return FALSE
;
808 if (g_blockEventsOnScroll
) return FALSE
;
810 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
813 printf( "OnButtonRelease from " );
814 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
815 printf( win->GetClassInfo()->GetClassName() );
819 wxEventType event_type
= wxEVT_NULL
;
821 switch (gdk_event
->button
)
823 case 1: event_type
= wxEVT_LEFT_UP
; break;
824 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
825 case 3: event_type
= wxEVT_RIGHT_UP
; break;
828 wxMouseEvent
event( event_type
);
829 event
.SetTimestamp( gdk_event
->time
);
830 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
831 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
832 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
833 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
834 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
835 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
836 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
837 event
.m_x
= (long)gdk_event
->x
;
838 event
.m_y
= (long)gdk_event
->y
;
840 // Some control don't have their own X window and thus cannot get
845 wxNode
*node
= win
->GetChildren().First();
848 wxWindow
*child
= (wxWindow
*)node
->Data();
850 if (child
->m_isStaticBox
)
852 // wxStaticBox is transparent in the box itself
855 int xx1
= child
->m_x
;
856 int yy1
= child
->m_y
;
857 int xx2
= child
->m_x
+ child
->m_width
;
858 int yy2
= child
->m_x
+ child
->m_height
;
861 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
863 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
865 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
867 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
870 event
.m_x
-= child
->m_x
;
871 event
.m_y
-= child
->m_y
;
878 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
879 (child
->m_x
<= event
.m_x
) &&
880 (child
->m_y
<= event
.m_y
) &&
881 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
882 (child
->m_y
+child
->m_height
>= event
.m_y
))
885 event
.m_x
-= child
->m_x
;
886 event
.m_y
-= child
->m_y
;
894 event
.SetEventObject( win
);
896 if (win
->GetEventHandler()->ProcessEvent( event
))
898 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
905 //-----------------------------------------------------------------------------
906 // "motion_notify_event"
907 //-----------------------------------------------------------------------------
909 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
912 wxapp_install_idle_handler();
914 if (!win
->m_hasVMT
) return FALSE
;
915 if (g_blockEventsOnDrag
) return FALSE
;
916 if (g_blockEventsOnScroll
) return FALSE
;
918 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
920 if (gdk_event
->is_hint
)
924 GdkModifierType state
;
925 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
928 gdk_event
->state
= state
;
932 printf( "OnMotion from " );
933 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
934 printf( win->GetClassInfo()->GetClassName() );
938 wxMouseEvent
event( wxEVT_MOTION
);
939 event
.SetTimestamp( gdk_event
->time
);
940 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
941 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
942 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
943 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
944 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
945 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
946 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
948 event
.m_x
= (long)gdk_event
->x
;
949 event
.m_y
= (long)gdk_event
->y
;
951 // Some control don't have their own X window and thus cannot get
956 wxNode
*node
= win
->GetChildren().First();
959 wxWindow
*child
= (wxWindow
*)node
->Data();
961 if (child
->m_isStaticBox
)
963 // wxStaticBox is transparent in the box itself
966 int xx1
= child
->m_x
;
967 int yy1
= child
->m_y
;
968 int xx2
= child
->m_x
+ child
->m_width
;
969 int yy2
= child
->m_x
+ child
->m_height
;
972 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
974 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
976 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
978 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
981 event
.m_x
-= child
->m_x
;
982 event
.m_y
-= child
->m_y
;
989 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
990 (child
->m_x
<= event
.m_x
) &&
991 (child
->m_y
<= event
.m_y
) &&
992 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
993 (child
->m_y
+child
->m_height
>= event
.m_y
))
996 event
.m_x
-= child
->m_x
;
997 event
.m_y
-= child
->m_y
;
1001 node
= node
->Next();
1005 event
.SetEventObject( win
);
1007 if (win
->GetEventHandler()->ProcessEvent( event
))
1009 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1016 //-----------------------------------------------------------------------------
1018 //-----------------------------------------------------------------------------
1020 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1023 wxapp_install_idle_handler();
1025 if (!win
->m_hasVMT
) return FALSE
;
1026 if (g_blockEventsOnDrag
) return FALSE
;
1028 g_focusWindow
= win
;
1030 if (win
->m_wxwindow
)
1032 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1034 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1036 printf( "SetFocus flag from " );
1037 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1038 printf( win->GetClassInfo()->GetClassName() );
1046 printf( "OnSetFocus from " );
1047 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1048 printf( win->GetClassInfo()->GetClassName() );
1050 printf( WXSTRINGCAST win->GetLabel() );
1054 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1055 event
.SetEventObject( win
);
1057 if (win
->GetEventHandler()->ProcessEvent( event
))
1059 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1066 //-----------------------------------------------------------------------------
1067 // "focus_out_event"
1068 //-----------------------------------------------------------------------------
1070 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1073 wxapp_install_idle_handler();
1075 if (!win
->m_hasVMT
) return FALSE
;
1076 if (g_blockEventsOnDrag
) return FALSE
;
1078 if (win
->m_wxwindow
)
1080 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1081 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1085 printf( "OnKillFocus from " );
1086 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1087 printf( win->GetClassInfo()->GetClassName() );
1091 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1092 event
.SetEventObject( win
);
1094 if (win
->GetEventHandler()->ProcessEvent( event
))
1096 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1103 //-----------------------------------------------------------------------------
1104 // "enter_notify_event"
1105 //-----------------------------------------------------------------------------
1107 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1110 wxapp_install_idle_handler();
1112 if (!win
->m_hasVMT
) return FALSE
;
1113 if (g_blockEventsOnDrag
) return FALSE
;
1115 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1117 if (widget
->window
&& win
->GetCursor().Ok() )
1118 gdk_window_set_cursor( widget
->window
, win
->GetCursor().GetCursor() );
1120 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1121 event
.SetTimestamp( gdk_event
->time
);
1122 event
.SetEventObject( win
);
1126 GdkModifierType state
= (GdkModifierType
)0;
1128 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1130 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1131 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1132 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1133 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1134 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1135 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1136 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1138 event
.m_x
= (long)x
;
1139 event
.m_y
= (long)y
;
1141 if (win
->GetEventHandler()->ProcessEvent( event
))
1143 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1150 //-----------------------------------------------------------------------------
1151 // "leave_notify_event"
1152 //-----------------------------------------------------------------------------
1154 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1157 wxapp_install_idle_handler();
1159 if (!win
->m_hasVMT
) return FALSE
;
1160 if (g_blockEventsOnDrag
) return FALSE
;
1162 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1164 if (widget
->window
&& win
->GetCursor().Ok() )
1165 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1167 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1168 event
.SetTimestamp( gdk_event
->time
);
1169 event
.SetEventObject( win
);
1173 GdkModifierType state
= (GdkModifierType
)0;
1175 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1177 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1178 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1179 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1180 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1181 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1182 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1183 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1185 event
.m_x
= (long)x
;
1186 event
.m_y
= (long)y
;
1188 if (win
->GetEventHandler()->ProcessEvent( event
))
1190 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1197 //-----------------------------------------------------------------------------
1198 // "value_changed" from m_vAdjust
1199 //-----------------------------------------------------------------------------
1201 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1204 wxapp_install_idle_handler();
1206 if (g_blockEventsOnDrag
) return;
1208 if (!win
->m_hasVMT
) return;
1210 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1211 if (fabs(diff
) < 0.2) return;
1212 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1214 wxEventType command
= wxEVT_NULL
;
1216 float line_step
= win
->m_vAdjust
->step_increment
;
1217 float page_step
= win
->m_vAdjust
->page_increment
;
1219 if (win
->IsScrolling())
1221 command
= wxEVT_SCROLL_THUMBTRACK
;
1225 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1226 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1227 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1228 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1229 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1230 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1231 else command
= wxEVT_SCROLL_THUMBTRACK
;
1234 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1236 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1237 event
.SetEventObject( win
);
1238 win
->GetEventHandler()->ProcessEvent( event
);
1241 //-----------------------------------------------------------------------------
1242 // "value_changed" from m_hAdjust
1243 //-----------------------------------------------------------------------------
1245 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1248 wxapp_install_idle_handler();
1250 if (g_blockEventsOnDrag
) return;
1251 if (!win
->m_hasVMT
) return;
1253 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1254 if (fabs(diff
) < 0.2) return;
1255 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1257 wxEventType command
= wxEVT_NULL
;
1259 float line_step
= win
->m_hAdjust
->step_increment
;
1260 float page_step
= win
->m_hAdjust
->page_increment
;
1262 if (win
->IsScrolling())
1264 command
= wxEVT_SCROLL_THUMBTRACK
;
1268 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1269 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1270 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1271 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1272 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1273 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1274 else command
= wxEVT_SCROLL_THUMBTRACK
;
1277 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1279 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1280 event
.SetEventObject( win
);
1281 win
->GetEventHandler()->ProcessEvent( event
);
1284 //-----------------------------------------------------------------------------
1285 // "changed" from m_vAdjust
1286 //-----------------------------------------------------------------------------
1288 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1291 wxapp_install_idle_handler();
1293 if (g_blockEventsOnDrag
) return;
1294 if (!win
->m_hasVMT
) return;
1296 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1297 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1299 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1300 event
.SetEventObject( win
);
1301 win
->GetEventHandler()->ProcessEvent( event
);
1304 //-----------------------------------------------------------------------------
1305 // "changed" from m_hAdjust
1306 //-----------------------------------------------------------------------------
1308 static void gtk_window_hscroll_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_hAdjust
->value
+0.5);
1319 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1320 event
.SetEventObject( win
);
1321 win
->GetEventHandler()->ProcessEvent( event
);
1324 //-----------------------------------------------------------------------------
1325 // "button_press_event" from scrollbar
1326 //-----------------------------------------------------------------------------
1328 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1329 GdkEventButton
*WXUNUSED(gdk_event
),
1333 wxapp_install_idle_handler();
1335 // don't test here as we can release the mouse while being over
1336 // a different window then the slider
1338 // if (gdk_event->window != widget->slider) return FALSE;
1340 win
->SetScrolling( TRUE
);
1345 //-----------------------------------------------------------------------------
1346 // "button_release_event" from scrollbar
1347 //-----------------------------------------------------------------------------
1349 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1350 GdkEventButton
*WXUNUSED(gdk_event
),
1354 // don't test here as we can release the mouse while being over
1355 // a different window then the slider
1357 // if (gdk_event->window != widget->slider) return FALSE;
1359 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1361 if (widget
== GTK_RANGE(scrolledWindow
->vscrollbar
))
1362 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1364 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1366 win
->SetScrolling( FALSE
);
1371 // ----------------------------------------------------------------------------
1372 // this wxWindowBase function is implemented here (in platform-specific file)
1373 // because it is static and so couldn't be made virtual
1374 // ----------------------------------------------------------------------------
1376 wxWindow
*wxWindowBase::FindFocus()
1378 return g_focusWindow
;
1381 //-----------------------------------------------------------------------------
1382 // "realize" from m_widget
1383 //-----------------------------------------------------------------------------
1385 /* we cannot set colours, fonts and cursors before the widget has
1386 been realized, so we do this directly after realization */
1389 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1392 wxapp_install_idle_handler();
1394 if (win
->m_delayedFont
)
1395 win
->SetFont( win
->GetFont() );
1397 if (win
->m_delayedBackgroundColour
)
1398 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1400 if (win
->m_delayedForegroundColour
)
1401 win
->SetForegroundColour( win
->GetForegroundColour() );
1403 win
->SetCursor( win
->GetCursor() );
1408 //-----------------------------------------------------------------------------
1409 // InsertChild for wxWindow.
1410 //-----------------------------------------------------------------------------
1412 /* Callback for wxWindow. This very strange beast has to be used because
1413 * C++ has no virtual methods in a constructor. We have to emulate a
1414 * virtual function here as wxNotebook requires a different way to insert
1415 * a child in it. I had opted for creating a wxNotebookPage window class
1416 * which would have made this superfluous (such in the MDI window system),
1417 * but no-one was listening to me... */
1419 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1421 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1422 GTK_WIDGET(child
->m_widget
),
1428 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1430 /* we now allow a window to get the focus as long as it
1431 doesn't have any children. */
1432 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1436 //-----------------------------------------------------------------------------
1438 //-----------------------------------------------------------------------------
1440 wxWindow
* wxGetActiveWindow()
1442 return g_focusWindow
;
1445 //-----------------------------------------------------------------------------
1447 //-----------------------------------------------------------------------------
1449 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1451 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
)
1452 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1455 void wxWindow::Init()
1461 m_widget
= (GtkWidget
*) NULL
;
1462 m_wxwindow
= (GtkWidget
*) NULL
;
1472 m_needParent
= TRUE
;
1473 m_isBeingDeleted
= FALSE
;
1475 m_hasScrolling
= FALSE
;
1476 m_isScrolling
= FALSE
;
1478 m_hAdjust
= (GtkAdjustment
*) NULL
;
1479 m_vAdjust
= (GtkAdjustment
*) NULL
;
1480 m_oldHorizontalPos
= 0.0;
1481 m_oldVerticalPos
= 0.0;
1484 m_scrollGC
= (GdkGC
*) NULL
;
1485 m_widgetStyle
= (GtkStyle
*) NULL
;
1487 m_insertCallback
= wxInsertChildInWindow
;
1489 m_isStaticBox
= FALSE
;
1490 m_acceptsFocus
= FALSE
;
1493 wxWindow::wxWindow()
1498 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1499 const wxPoint
&pos
, const wxSize
&size
,
1500 long style
, const wxString
&name
)
1504 Create( parent
, id
, pos
, size
, style
, name
);
1507 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1508 const wxPoint
&pos
, const wxSize
&size
,
1509 long style
, const wxString
&name
)
1511 PreCreation( parent
, id
, pos
, size
, style
, name
);
1513 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1514 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1517 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1520 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1523 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1524 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1527 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1528 scroll_class
->scrollbar_spacing
= 0;
1530 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1532 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1533 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1535 m_wxwindow
= gtk_myfixed_new();
1538 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1541 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1543 #if (GTK_MINOR_VERSION > 0)
1544 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1546 if (HasFlag(wxRAISED_BORDER
))
1548 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1550 else if (HasFlag(wxSUNKEN_BORDER
))
1552 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1556 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1558 #else // GTK_MINOR_VERSION == 0
1559 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1561 if (HasFlag(wxRAISED_BORDER
))
1563 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1565 else if (HasFlag(wxSUNKEN_BORDER
))
1567 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1571 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1573 #endif // GTK_MINOR_VERSION
1575 if (HasFlag(wxTAB_TRAVERSAL
))
1577 /* we now allow a window to get the focus as long as it
1578 doesn't have any children. */
1579 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1580 m_acceptsFocus
= FALSE
;
1584 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1585 m_acceptsFocus
= TRUE
;
1588 #if (GTK_MINOR_VERSION == 0)
1589 // shut the viewport up
1590 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1591 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1592 #endif // GTK_MINOR_VERSION == 0
1594 // I _really_ don't want scrollbars in the beginning
1595 m_vAdjust
->lower
= 0.0;
1596 m_vAdjust
->upper
= 1.0;
1597 m_vAdjust
->value
= 0.0;
1598 m_vAdjust
->step_increment
= 1.0;
1599 m_vAdjust
->page_increment
= 1.0;
1600 m_vAdjust
->page_size
= 5.0;
1601 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1602 m_hAdjust
->lower
= 0.0;
1603 m_hAdjust
->upper
= 1.0;
1604 m_hAdjust
->value
= 0.0;
1605 m_hAdjust
->step_increment
= 1.0;
1606 m_hAdjust
->page_increment
= 1.0;
1607 m_hAdjust
->page_size
= 5.0;
1608 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1610 // these handlers block mouse events to any window during scrolling such as
1611 // motion events and prevent GTK and wxWindows from fighting over where the
1614 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1615 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1617 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1618 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1620 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1621 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1623 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1624 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1626 // these handlers get notified when screen updates are required either when
1627 // scrolling or when the window size (and therefore scrollbar configuration)
1630 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1631 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1632 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1633 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1635 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1636 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1637 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1638 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1640 gtk_widget_show( m_wxwindow
);
1643 m_parent
->DoAddChild( this );
1652 wxWindow::~wxWindow()
1654 m_isBeingDeleted
= TRUE
;
1663 m_parent
->RemoveChild( this );
1667 gtk_style_unref( m_widgetStyle
);
1668 m_widgetStyle
= (GtkStyle
*) NULL
;
1673 gdk_gc_unref( m_scrollGC
);
1674 m_scrollGC
= (GdkGC
*) NULL
;
1679 gtk_widget_destroy( m_wxwindow
);
1680 m_wxwindow
= (GtkWidget
*) NULL
;
1685 gtk_widget_destroy( m_widget
);
1686 m_widget
= (GtkWidget
*) NULL
;
1690 void wxWindow::PreCreation( wxWindow
*parent
,
1695 const wxString
&name
)
1697 wxASSERT_MSG( !m_needParent
|| parent
, _T("Need complete parent.") );
1699 if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) )
1701 wxFAIL_MSG(_T("window creation failed"));
1704 m_width
= WidthDefault(size
.x
);
1705 m_height
= HeightDefault(size
.y
);
1710 if (!parent
) /* some reasonable defaults */
1714 m_x
= (gdk_screen_width () - m_width
) / 2;
1715 if (m_x
< 10) m_x
= 10;
1719 m_y
= (gdk_screen_height () - m_height
) / 2;
1720 if (m_y
< 10) m_y
= 10;
1725 void wxWindow::PostCreation()
1727 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1731 /* these get reported to wxWindows -> wxPaintEvent */
1732 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1733 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1735 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1736 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1738 #if (GTK_MINOR_VERSION > 0)
1739 /* these are called when the "sunken" or "raised" borders are drawn */
1740 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1741 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1743 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1744 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1748 GtkWidget
*connect_widget
= GetConnectWidget();
1750 ConnectWidget( connect_widget
);
1752 /* we cannot set colours, fonts and cursors before the widget has
1753 been realized, so we do this directly after realization */
1754 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1755 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1760 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1762 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1763 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1765 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1766 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1768 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1769 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1771 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1772 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1774 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1775 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1777 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1778 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1780 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1781 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1783 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1784 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1786 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1787 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1790 bool wxWindow::Destroy()
1792 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1796 return wxWindowBase::Destroy();
1799 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1801 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1802 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1804 if (m_resizing
) return; /* I don't like recursions */
1807 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1809 /* don't set the size for children of wxNotebook, just take the values. */
1817 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1819 if (x
!= -1) m_x
= x
;
1820 if (y
!= -1) m_y
= y
;
1821 if (width
!= -1) m_width
= width
;
1822 if (height
!= -1) m_height
= height
;
1832 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1834 if (width
== -1) m_width
= 80;
1837 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1839 if (height
== -1) m_height
= 26;
1842 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1843 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1844 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1845 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1849 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1851 /* the default button has a border around it */
1855 /* this is the result of hours of debugging: the following code
1856 means that if we have a m_wxwindow and we set the size of
1857 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
1858 automatically propagate its size down to its m_wxwindow,
1859 which is its client area. therefore, we have to tell the
1860 client area directly that it has to resize itself.
1861 this will lead to that m_widget (GtkScrolledWindow) will
1862 calculate how much size it needs for scrollbars etc and
1863 it will then call XXX_size_allocate of its child, which
1864 is m_wxwindow. m_wxwindow in turn will do the same with its
1865 children and so on. problems can arise if this happens
1866 before all the children have been realized as some widgets
1867 stupidy need to be realized during XXX_size_allocate (e.g.
1868 GtkNotebook) and they will segv if called otherwise. this
1869 emergency is tested in gtk_myfixed_size_allocate. Normally
1870 this shouldn't be needed and only gtk_widget_queue_resize()
1871 should be enough to provoke a resize at the next appropriate
1872 moment, but this seems to fail, e.g. when a wxNotebook contains
1873 a wxSplitterWindow: the splitter window's children won't
1874 show up properly resized then. */
1876 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
1881 m_height
+2*border
);
1886 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1887 event
.SetEventObject( this );
1888 GetEventHandler()->ProcessEvent( event
);
1893 void wxWindow::OnInternalIdle()
1898 void wxWindow::DoGetSize( int *width
, int *height
) const
1900 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1902 if (width
) (*width
) = m_width
;
1903 if (height
) (*height
) = m_height
;
1906 void wxWindow::DoSetClientSize( int width
, int height
)
1908 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1912 SetSize( width
, height
);
1919 if (!m_hasScrolling
)
1921 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1923 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1925 dw
+= 2 * window_class
->xthickness
;
1926 dh
+= 2 * window_class
->ythickness
;
1931 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1932 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1934 #if (GTK_MINOR_VERSION == 0)
1935 GtkWidget
*viewport
= scroll_window
->viewport
;
1936 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1938 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1940 dw
+= 2 * viewport_class
->xthickness
;
1941 dh
+= 2 * viewport_class
->ythickness
;
1946 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1947 GtkWidget *vscrollbar = scroll_window->vscrollbar;
1949 we use this instead: range.slider_width = 11 + 2*2pts edge
1952 if (scroll_window
->vscrollbar_visible
)
1954 dw
+= 15; /* dw += vscrollbar->allocation.width; */
1955 dw
+= scroll_class
->scrollbar_spacing
;
1958 if (scroll_window
->hscrollbar_visible
)
1960 dh
+= 15; /* dh += hscrollbar->allocation.height; */
1961 dw
+= scroll_class
->scrollbar_spacing
;
1965 SetSize( width
+dw
, height
+dh
);
1969 void wxWindow::DoGetClientSize( int *width
, int *height
) const
1971 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1975 if (width
) (*width
) = m_width
;
1976 if (height
) (*height
) = m_height
;
1983 if (!m_hasScrolling
)
1985 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1987 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1989 dw
+= 2 * window_class
->xthickness
;
1990 dh
+= 2 * window_class
->ythickness
;
1995 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1996 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1998 #if (GTK_MINOR_VERSION == 0)
1999 GtkWidget
*viewport
= scroll_window
->viewport
;
2000 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2002 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) )
2004 dw
+= 2 * viewport_class
->xthickness
;
2005 dh
+= 2 * viewport_class
->ythickness
;
2009 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2010 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2012 we use this instead: range.slider_width = 11 + 2*2pts edge
2015 if (scroll_window
->vscrollbar_visible
)
2017 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2018 dw
+= scroll_class
->scrollbar_spacing
;
2021 if (scroll_window
->hscrollbar_visible
)
2023 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2024 dh
+= scroll_class
->scrollbar_spacing
;
2028 if (width
) (*width
) = m_width
- dw
;
2029 if (height
) (*height
) = m_height
- dh
;
2033 void wxWindow::DoGetPosition( int *x
, int *y
) const
2035 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2041 void wxWindow::ClientToScreen( int *x
, int *y
) const
2043 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2045 if (!m_widget
->window
) return;
2047 GdkWindow
*source
= (GdkWindow
*) NULL
;
2049 source
= m_wxwindow
->window
;
2051 source
= m_widget
->window
;
2055 gdk_window_get_origin( source
, &org_x
, &org_y
);
2059 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2061 org_x
+= m_widget
->allocation
.x
;
2062 org_y
+= m_widget
->allocation
.y
;
2070 void wxWindow::ScreenToClient( int *x
, int *y
) const
2072 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2074 if (!m_widget
->window
) return;
2076 GdkWindow
*source
= (GdkWindow
*) NULL
;
2078 source
= m_wxwindow
->window
;
2080 source
= m_widget
->window
;
2084 gdk_window_get_origin( source
, &org_x
, &org_y
);
2088 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2090 org_x
+= m_widget
->allocation
.x
;
2091 org_y
+= m_widget
->allocation
.y
;
2099 bool wxWindow::Show( bool show
)
2101 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2103 if (!wxWindowBase::Show(show
))
2110 gtk_widget_show( m_widget
);
2112 gtk_widget_hide( m_widget
);
2117 bool wxWindow::Enable( bool enable
)
2119 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2121 if (!wxWindowBase::Enable(enable
))
2127 gtk_widget_set_sensitive( m_widget
, enable
);
2129 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2134 int wxWindow::GetCharHeight() const
2136 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2138 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2140 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2142 return font
->ascent
+ font
->descent
;
2145 int wxWindow::GetCharWidth() const
2147 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2149 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2151 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2153 return gdk_string_width( font
, "H" );
2156 void wxWindow::GetTextExtent( const wxString
& string
,
2160 int *externalLeading
,
2161 const wxFont
*theFont
) const
2163 wxFont fontToUse
= m_font
;
2164 if (theFont
) fontToUse
= *theFont
;
2166 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2168 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2169 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2170 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2171 if (descent
) (*descent
) = font
->descent
;
2172 if (externalLeading
) (*externalLeading
) = 0; // ??
2175 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2177 event
.SetEventType( wxEVT_CHAR
);
2179 if (!GetEventHandler()->ProcessEvent( event
))
2185 void wxWindow::SetFocus()
2187 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2189 GtkWidget
*connect_widget
= GetConnectWidget();
2192 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2194 gtk_widget_grab_focus (connect_widget
);
2196 else if (GTK_IS_CONTAINER(connect_widget
))
2198 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2206 bool wxWindow::AcceptsFocus() const
2208 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2211 bool wxWindow::Reparent( wxWindow
*newParent
)
2213 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2215 gtk_widget_unparent( m_widget
);
2217 if ( !wxWindowBase::Reparent(newParent
) )
2223 void wxWindow::Raise()
2225 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2227 if (!m_widget
->window
) return;
2229 gdk_window_raise( m_widget
->window
);
2232 void wxWindow::Lower()
2234 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2236 if (!m_widget
->window
) return;
2238 gdk_window_lower( m_widget
->window
);
2241 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2243 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2245 if (!wxWindowBase::SetCursor(cursor
))
2247 // don't leave if the GTK widget has just
2249 if (!m_delayedCursor
) return FALSE
;
2252 GtkWidget
*connect_widget
= GetConnectWidget();
2253 if (!connect_widget
->window
)
2255 // indicate that a new style has been set
2256 // but it couldn't get applied as the
2257 // widget hasn't been realized yet.
2258 m_delayedCursor
= TRUE
;
2260 // pretend we have done something
2264 if ((m_widget
) && (m_widget
->window
))
2265 gdk_window_set_cursor( m_widget
->window
, GetCursor().GetCursor() );
2267 if ((m_wxwindow
) && (m_wxwindow
->window
))
2268 gdk_window_set_cursor( m_wxwindow
->window
, GetCursor().GetCursor() );
2274 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2279 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2281 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2283 if (!m_widget
->window
) return;
2285 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2289 gdk_window_clear_area( m_wxwindow
->window
,
2291 rect
->width
, rect
->height
);
2295 gdk_window_clear( m_wxwindow
->window
);
2302 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2304 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2308 GdkRectangle gdk_rect
;
2309 gdk_rect
.x
= rect
->x
;
2310 gdk_rect
.y
= rect
->y
;
2311 gdk_rect
.width
= rect
->width
;
2312 gdk_rect
.height
= rect
->height
;
2315 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2317 gtk_widget_draw( m_widget
, &gdk_rect
);
2321 void wxWindow::Clear()
2323 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2325 if (!m_widget
->window
) return;
2327 if (m_wxwindow
&& m_wxwindow
->window
)
2329 gdk_window_clear( m_wxwindow
->window
);
2334 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2336 wxWindowBase::DoSetToolTip(tip
);
2339 m_tooltip
->Apply( this );
2342 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2344 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2346 #endif // wxUSE_TOOLTIPS
2348 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2350 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2352 if (!wxWindowBase::SetBackgroundColour(colour
))
2354 // don't leave if the GTK widget has just
2356 if (!m_delayedBackgroundColour
) return FALSE
;
2359 GtkWidget
*connect_widget
= GetConnectWidget();
2360 if (!connect_widget
->window
)
2362 // indicate that a new style has been set
2363 // but it couldn't get applied as the
2364 // widget hasn't been realized yet.
2365 m_delayedBackgroundColour
= TRUE
;
2367 // pretend we have done something
2371 if (m_wxwindow
&& m_wxwindow
->window
)
2373 /* wxMSW doesn't clear the window here. I don't do that either to
2374 provide compatibility. call Clear() to do the job. */
2376 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2377 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2380 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2382 if (sysbg
== m_backgroundColour
)
2384 m_backgroundColour
= wxNullColour
;
2386 m_backgroundColour
= sysbg
;
2396 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2398 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2400 if (!wxWindowBase::SetForegroundColour(colour
))
2402 // don't leave if the GTK widget has just
2404 if (!m_delayedForegroundColour
) return FALSE
;
2407 GtkWidget
*connect_widget
= GetConnectWidget();
2408 if (!connect_widget
->window
)
2410 // indicate that a new style has been set
2411 // but it couldn't get applied as the
2412 // widget hasn't been realized yet.
2413 m_delayedForegroundColour
= TRUE
;
2415 // pretend we have done something
2419 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2420 if (sysbg
== m_foregroundColour
)
2422 m_backgroundColour
= wxNullColour
;
2424 m_backgroundColour
= sysbg
;
2434 GtkStyle
*wxWindow::GetWidgetStyle()
2436 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2438 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2440 return m_widgetStyle
;
2443 void wxWindow::SetWidgetStyle()
2445 GtkStyle
*style
= GetWidgetStyle();
2447 gdk_font_unref( style
->font
);
2448 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2450 if (m_foregroundColour
.Ok())
2452 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2453 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2454 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2455 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2458 if (m_backgroundColour
.Ok())
2460 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2461 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2462 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2463 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2464 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2465 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2466 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2467 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2468 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2472 void wxWindow::ApplyWidgetStyle()
2476 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2478 menu
->SetInvokingWindow( win
);
2479 wxNode
*node
= menu
->GetItems().First();
2482 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2483 if (menuitem
->IsSubMenu())
2485 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2487 node
= node
->Next();
2491 static gint gs_pop_x
= 0;
2492 static gint gs_pop_y
= 0;
2494 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2498 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2503 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2505 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2507 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2509 SetInvokingWindow( menu
, this );
2517 GTK_MENU(menu
->m_menu
),
2518 (GtkWidget
*) NULL
, // parent menu shell
2519 (GtkWidget
*) NULL
, // parent menu item
2520 (GtkMenuPositionFunc
) pop_pos_callback
,
2521 (gpointer
) this, // client data
2522 0, // button used to activate it
2523 0 //gs_timeLastClick // the time of activation
2528 #if wxUSE_DRAG_AND_DROP
2530 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2532 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2534 GtkWidget
*dnd_widget
= GetConnectWidget();
2536 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2538 if (m_dropTarget
) delete m_dropTarget
;
2539 m_dropTarget
= dropTarget
;
2541 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2544 #endif // wxUSE_DRAG_AND_DROP
2546 GtkWidget
* wxWindow::GetConnectWidget()
2548 GtkWidget
*connect_widget
= m_widget
;
2549 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2551 return connect_widget
;
2554 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2556 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2557 return (window
== m_widget
->window
);
2560 bool wxWindow::SetFont( const wxFont
&font
)
2562 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T( "invalid window") );
2564 if (!wxWindowBase::SetFont(font
))
2566 // don't leave if the GTK widget has just
2568 if (!m_delayedFont
) return FALSE
;
2571 GtkWidget
*connect_widget
= GetConnectWidget();
2572 if (!connect_widget
->window
)
2574 // indicate that a new style has been set
2575 // but it couldn't get applied as the
2576 // widget hasn't been realized yet.
2577 m_delayedFont
= TRUE
;
2579 // pretend we have done something
2583 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2584 if ( sysbg
== m_backgroundColour
)
2586 m_backgroundColour
= wxNullColour
;
2588 m_backgroundColour
= sysbg
;
2598 void wxWindow::CaptureMouse()
2600 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2602 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
2604 GtkWidget
*connect_widget
= GetConnectWidget();
2605 if (!connect_widget
->window
) return;
2607 gtk_grab_add( connect_widget
);
2608 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2610 (GDK_BUTTON_PRESS_MASK
|
2611 GDK_BUTTON_RELEASE_MASK
|
2612 GDK_POINTER_MOTION_MASK
),
2619 void wxWindow::ReleaseMouse()
2621 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2623 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
2625 GtkWidget
*connect_widget
= GetConnectWidget();
2626 if (!connect_widget
->window
) return;
2628 gtk_grab_remove( connect_widget
);
2629 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2630 g_capturing
= FALSE
;
2633 bool wxWindow::IsRetained() const
2638 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2639 int range
, bool refresh
)
2641 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2643 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2645 m_hasScrolling
= TRUE
;
2647 if (orient
== wxHORIZONTAL
)
2649 float fpos
= (float)pos
;
2650 float frange
= (float)range
;
2651 float fthumb
= (float)thumbVisible
;
2652 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2653 if (fpos
< 0.0) fpos
= 0.0;
2655 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2656 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2658 SetScrollPos( orient
, pos
, refresh
);
2662 m_oldHorizontalPos
= fpos
;
2664 m_hAdjust
->lower
= 0.0;
2665 m_hAdjust
->upper
= frange
;
2666 m_hAdjust
->value
= fpos
;
2667 m_hAdjust
->step_increment
= 1.0;
2668 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2669 m_hAdjust
->page_size
= fthumb
;
2673 float fpos
= (float)pos
;
2674 float frange
= (float)range
;
2675 float fthumb
= (float)thumbVisible
;
2676 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2677 if (fpos
< 0.0) fpos
= 0.0;
2679 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2680 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2682 SetScrollPos( orient
, pos
, refresh
);
2686 m_oldVerticalPos
= fpos
;
2688 m_vAdjust
->lower
= 0.0;
2689 m_vAdjust
->upper
= frange
;
2690 m_vAdjust
->value
= fpos
;
2691 m_vAdjust
->step_increment
= 1.0;
2692 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2693 m_vAdjust
->page_size
= fthumb
;
2696 if (orient
== wxHORIZONTAL
)
2697 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2699 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2702 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2704 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2706 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2708 if (orient
== wxHORIZONTAL
)
2710 float fpos
= (float)pos
;
2711 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2712 if (fpos
< 0.0) fpos
= 0.0;
2713 m_oldHorizontalPos
= fpos
;
2715 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2716 m_hAdjust
->value
= fpos
;
2720 float fpos
= (float)pos
;
2721 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2722 if (fpos
< 0.0) fpos
= 0.0;
2723 m_oldVerticalPos
= fpos
;
2725 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2726 m_vAdjust
->value
= fpos
;
2729 if (!m_isScrolling
) /* prevent recursion */
2731 if (m_wxwindow
->window
)
2733 if (orient
== wxHORIZONTAL
)
2734 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2736 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2741 int wxWindow::GetScrollThumb( int orient
) const
2743 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2745 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2747 if (orient
== wxHORIZONTAL
)
2748 return (int)(m_hAdjust
->page_size
+0.5);
2750 return (int)(m_vAdjust
->page_size
+0.5);
2753 int wxWindow::GetScrollPos( int orient
) const
2755 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2757 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2759 if (orient
== wxHORIZONTAL
)
2760 return (int)(m_hAdjust
->value
+0.5);
2762 return (int)(m_vAdjust
->value
+0.5);
2765 int wxWindow::GetScrollRange( int orient
) const
2767 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2769 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2771 if (orient
== wxHORIZONTAL
)
2772 return (int)(m_hAdjust
->upper
+0.5);
2774 return (int)(m_vAdjust
->upper
+0.5);
2777 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2779 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2781 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2785 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2786 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2791 GetClientSize( &cw
, &ch
);
2792 int w
= cw
- abs(dx
);
2793 int h
= ch
- abs(dy
);
2795 if ((h
< 0) || (w
< 0))
2803 if (dx
< 0) s_x
= -dx
;
2804 if (dy
< 0) s_y
= -dy
;
2807 if (dx
> 0) d_x
= dx
;
2808 if (dy
> 0) d_y
= dy
;
2810 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2811 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2814 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2815 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2816 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2817 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2819 Refresh( TRUE
, &rect
);
2822 wxNode
*node
= m_children
.First();
2825 wxWindow
*child
= (wxWindow
*) node
->Data();
2826 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
2827 node
= node
->Next();
2831 void wxWindow::SetScrolling(bool scroll
)
2833 m_isScrolling
= g_blockEventsOnScroll
= scroll
;