1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "window.h"
16 #include "wx/window.h"
20 #include "wx/layout.h"
22 #include "wx/dialog.h"
23 #include "wx/msgdlg.h"
25 #if wxUSE_DRAG_AND_DROP
30 #include "wx/tooltip.h"
34 #include "wx/statusbr.h"
36 #include "wx/settings.h"
43 #include "gdk/gdkprivate.h"
44 #include "gdk/gdkkeysyms.h"
45 #include "wx/gtk/win_gtk.h"
47 //-----------------------------------------------------------------------------
48 // documentation on internals
49 //-----------------------------------------------------------------------------
52 I have been asked several times about writing some documentation about
53 the GTK port of wxWindows, especially its internal structures. Obviously,
54 you cannot understand wxGTK without knowing a little about the GTK, but
55 some more information about what the wxWindow, which is the base class
56 for all other window classes, does seems required as well.
58 What does wxWindow do? It contains the common interface for the following
59 jobs of its descendants:
61 1) Define the rudimentary behaviour common to all window classes, such as
62 resizing, intercepting user input (so as to make it possible to use these
63 events for special purposes in a derived class), window names etc.
65 2) Provide the possibility to contain and manage children, if the derived
66 class is allowed to contain children, which holds true for those window
67 classes which do not display a native GTK widget. To name them, these
68 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
69 work classes are a special case and are handled a bit differently from
70 the rest. The same holds true for the wxNotebook class.
72 3) Provide the possibility to draw into a client area of a window. This,
73 too, only holds true for classes that do not display a native GTK widget
76 4) Provide the entire mechanism for scrolling widgets. This actual inter-
77 face for this is usually in wxScrolledWindow, but the GTK implementation
80 5) A multitude of helper or extra methods for special purposes, such as
81 Drag'n'Drop, managing validators etc.
83 Normally one might expect, that one wxWindows window would always correspond
84 to one GTK widget. Under GTK, there is no such allround widget that has all
85 the functionality. Moreover, the GTK defines a client area as a different
86 widget from the actual widget you are handling. Last but not least some
87 special classes (e.g. wxFrame) handle different categories of widgets and
88 still have the possibility to draw something in the client area.
89 It was therefore required to write a special purpose GTK widget, that would
90 represent a client area in the sense of wxWindows capable to do the jobs
91 2), 3) and 4). I have written this class and it resides in win_gtk.c of
94 All windows must have a widget, with which they interact with other under-
95 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
96 thw wxWindow class has a member variable called m_widget which holds a
97 pointer to this widget. When the window class represents a GTK native widget,
98 this is (in most cases) the only GTK widget the class manages. E.g. the
99 wxStatitText class handles only a GtkLabel widget a pointer to which you
100 can find in m_widget (defined in wxWindow)
102 When the class has a client area for drawing into and for containing children
103 it has to handle the client area widget (of the type GtkMyFixed, defined in
104 win_gtk.c), but there could be any number of widgets, handled by a class
105 The common rule for all windows is only, that the widget that interacts with
106 the rest of GTK must be referenced in m_widget and all other widgets must be
107 children of this widget on the GTK level. The top-most widget, which also
108 represents the client area, must be in the m_wxwindow field and must be of
111 As I said, the window classes that display a GTK native widget only have
112 one widget, so in the case of e.g. the wxButton class m_widget holds a
113 pointer to a GtkButton widget. But windows with client areas (for drawing
114 and children) have a m_widget field that is a pointer to a GtkScrolled-
115 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
116 one is (in the GTK sense) a child of the GtkScrolledWindow.
118 If the m_wxwindow field is set, then all input to this widget is inter-
119 cepted and sent to the wxWindows class. If not, all input to the widget
120 that gets pointed to by m_widget gets intercepted and sent to the class.
124 //-----------------------------------------------------------------------------
126 //-----------------------------------------------------------------------------
128 extern wxList wxPendingDelete
;
129 extern bool g_blockEventsOnDrag
;
130 extern bool g_blockEventsOnScroll
;
131 static bool g_capturing
= FALSE
;
132 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
134 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
135 the last click here */
136 static guint32 gs_timeLastClick
= 0;
138 //-----------------------------------------------------------------------------
140 //-----------------------------------------------------------------------------
144 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
145 GdkEvent
*WXUNUSED(event
),
148 // to enable logging of the focus events replace 0 with 1
150 static bool s_done
= FALSE
;
153 wxLog::AddTraceMask("focus");
157 wxLogTrace(_T("FOCUS NOW AT: %s"), name
);
162 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
168 wxChar
*s
= new wxChar
[tmp
.Length()+1];
172 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
173 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
178 //-----------------------------------------------------------------------------
180 //-----------------------------------------------------------------------------
182 extern void wxapp_install_idle_handler();
183 extern bool g_isIdle
;
185 //-----------------------------------------------------------------------------
186 // local code (see below)
187 //-----------------------------------------------------------------------------
189 #if (GTK_MINOR_VERSION > 0)
191 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
199 if (win
->HasScrolling())
201 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
202 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
205 GtkWidget *hscrollbar = scroll_window->hscrollbar;
206 GtkWidget *vscrollbar = scroll_window->vscrollbar;
208 we use this instead: range.slider_width = 11 + 2*2pts edge
211 if (scroll_window
->vscrollbar_visible
)
213 dw
+= 15; /* dw += vscrollbar->allocation.width; */
214 dw
+= scroll_class
->scrollbar_spacing
;
217 if (scroll_window
->hscrollbar_visible
)
219 dh
+= 15; /* dh += hscrollbar->allocation.height; */
220 dw
+= scroll_class
->scrollbar_spacing
;
226 if (GTK_WIDGET_NO_WINDOW (widget
))
228 dx
+= widget
->allocation
.x
;
229 dy
+= widget
->allocation
.y
;
232 if (win
->HasFlag(wxRAISED_BORDER
))
234 gtk_draw_shadow( widget
->style
,
239 win
->m_width
-dw
, win
->m_height
-dh
);
243 if (win
->HasFlag(wxSUNKEN_BORDER
))
245 gtk_draw_shadow( widget
->style
,
250 win
->m_width
-dw
, win
->m_height
-dh
);
255 //-----------------------------------------------------------------------------
256 // "expose_event" of m_widget
257 //-----------------------------------------------------------------------------
259 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
261 if (gdk_event
->count
> 0) return;
262 draw_frame( widget
, win
);
265 //-----------------------------------------------------------------------------
266 // "draw" of m_wxwindow
267 //-----------------------------------------------------------------------------
269 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
271 draw_frame( widget
, win
);
274 #endif // GTK_MINOR_VERSION > 0
276 //-----------------------------------------------------------------------------
277 // "expose_event" of m_wxwindow
278 //-----------------------------------------------------------------------------
280 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
282 if ( !win
->m_hasVMT
)
285 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
287 gdk_event
->area
.width
,
288 gdk_event
->area
.height
);
290 if ( gdk_event
->count
> 0 )
294 printf( "OnExpose from " );
295 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
296 printf( win->GetClassInfo()->GetClassName() );
300 wxPaintEvent
event( win
->GetId() );
301 event
.SetEventObject( win
);
302 win
->GetEventHandler()->ProcessEvent( event
);
304 win
->GetUpdateRegion().Clear();
307 //-----------------------------------------------------------------------------
308 // "draw" of m_wxwindow
309 //-----------------------------------------------------------------------------
311 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
314 wxapp_install_idle_handler();
319 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
320 rect
->width
, rect
->height
);
322 wxPaintEvent
event( win
->GetId() );
323 event
.SetEventObject( win
);
324 win
->GetEventHandler()->ProcessEvent( event
);
326 win
->GetUpdateRegion().Clear();
329 //-----------------------------------------------------------------------------
330 // "key_press_event" from any window
331 //-----------------------------------------------------------------------------
333 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
336 wxapp_install_idle_handler();
338 if (!win
->m_hasVMT
) return FALSE
;
339 if (g_blockEventsOnDrag
) return FALSE
;
342 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
343 if (gdk_event->state & GDK_SHIFT_MASK)
344 printf( "ShiftDown.\n" );
346 printf( "ShiftUp.\n" );
347 if (gdk_event->state & GDK_CONTROL_MASK)
348 printf( "ControlDown.\n" );
350 printf( "ControlUp.\n" );
355 switch (gdk_event
->keyval
)
357 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
358 case GDK_ISO_Left_Tab
:
360 case GDK_Tab
: key_code
= WXK_TAB
; break;
361 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
362 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
363 case GDK_Return
: key_code
= WXK_RETURN
; break;
364 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
365 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
366 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
367 case GDK_Delete
: key_code
= WXK_DELETE
; break;
368 case GDK_Home
: key_code
= WXK_HOME
; break;
369 case GDK_Left
: key_code
= WXK_LEFT
; break;
370 case GDK_Up
: key_code
= WXK_UP
; break;
371 case GDK_Right
: key_code
= WXK_RIGHT
; break;
372 case GDK_Down
: key_code
= WXK_DOWN
; break;
373 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
374 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
375 case GDK_Next
: key_code
= WXK_NEXT
; break;
376 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
377 case GDK_End
: key_code
= WXK_END
; break;
378 case GDK_Begin
: key_code
= WXK_HOME
; break;
379 case GDK_Select
: key_code
= WXK_SELECT
; break;
380 case GDK_Print
: key_code
= WXK_PRINT
; break;
381 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
382 case GDK_Insert
: key_code
= WXK_INSERT
; break;
383 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
384 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
385 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
386 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
387 case GDK_KP_Up
: key_code
= WXK_UP
; break;
388 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
389 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
390 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
391 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
392 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
393 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
394 case GDK_KP_End
: key_code
= WXK_END
; break;
395 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
396 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
397 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
398 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
399 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
400 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
401 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
402 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
403 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
404 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
405 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
406 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
407 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
408 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
409 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
410 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
411 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
412 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
413 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
414 case GDK_F1
: key_code
= WXK_F1
; break;
415 case GDK_F2
: key_code
= WXK_F2
; break;
416 case GDK_F3
: key_code
= WXK_F3
; break;
417 case GDK_F4
: key_code
= WXK_F4
; break;
418 case GDK_F5
: key_code
= WXK_F5
; break;
419 case GDK_F6
: key_code
= WXK_F6
; break;
420 case GDK_F7
: key_code
= WXK_F7
; break;
421 case GDK_F8
: key_code
= WXK_F8
; break;
422 case GDK_F9
: key_code
= WXK_F9
; break;
423 case GDK_F10
: key_code
= WXK_F10
; break;
424 case GDK_F11
: key_code
= WXK_F11
; break;
425 case GDK_F12
: key_code
= WXK_F12
; break;
428 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
429 key_code
= gdk_event
->keyval
;
433 if (!key_code
) return FALSE
;
435 wxKeyEvent
event( wxEVT_KEY_DOWN
);
436 event
.SetTimestamp( gdk_event
->time
);
437 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
438 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
439 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
440 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
441 event
.m_keyCode
= key_code
;
444 event
.SetEventObject( win
);
446 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
450 wxWindow
*ancestor
= win
;
453 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
456 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
457 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
460 ancestor
= ancestor
->GetParent();
464 // win is a control: tab can be propagated up
466 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
467 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
469 wxNavigationKeyEvent new_event
;
470 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
471 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
472 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
473 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
474 new_event
.SetCurrentFocus( win
);
475 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
479 (gdk_event
->keyval
== GDK_Escape
) )
481 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
482 new_event
.SetEventObject( win
);
483 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
487 Damn, I forgot why this didn't work, but it didn't work.
489 // win is a panel: up can be propagated to the panel
490 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
491 (gdk_event->keyval == GDK_Up))
493 win->m_parent->SetFocus();
497 // win is a panel: left/right can be propagated to the panel
498 if ((!ret) && (win->m_wxwindow) &&
499 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
500 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
502 wxNavigationKeyEvent new_event;
503 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
504 new_event.SetCurrentFocus( win );
505 ret = win->GetEventHandler()->ProcessEvent( new_event );
511 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
518 //-----------------------------------------------------------------------------
519 // "key_release_event" from any window
520 //-----------------------------------------------------------------------------
522 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
525 wxapp_install_idle_handler();
527 if (!win
->m_hasVMT
) return FALSE
;
528 if (g_blockEventsOnDrag
) return FALSE
;
531 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
532 if (gdk_event->state & GDK_SHIFT_MASK)
533 printf( "ShiftDown.\n" );
535 printf( "ShiftUp.\n" );
536 if (gdk_event->state & GDK_CONTROL_MASK)
537 printf( "ControlDown.\n" );
539 printf( "ControlUp.\n" );
544 switch (gdk_event
->keyval
)
546 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
547 case GDK_ISO_Left_Tab
:
549 case GDK_Tab
: key_code
= WXK_TAB
; break;
550 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
551 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
552 case GDK_Return
: key_code
= WXK_RETURN
; break;
553 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
554 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
555 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
556 case GDK_Delete
: key_code
= WXK_DELETE
; break;
557 case GDK_Home
: key_code
= WXK_HOME
; break;
558 case GDK_Left
: key_code
= WXK_LEFT
; break;
559 case GDK_Up
: key_code
= WXK_UP
; break;
560 case GDK_Right
: key_code
= WXK_RIGHT
; break;
561 case GDK_Down
: key_code
= WXK_DOWN
; break;
562 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
563 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
564 case GDK_Next
: key_code
= WXK_NEXT
; break;
565 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
566 case GDK_End
: key_code
= WXK_END
; break;
567 case GDK_Begin
: key_code
= WXK_HOME
; break;
568 case GDK_Select
: key_code
= WXK_SELECT
; break;
569 case GDK_Print
: key_code
= WXK_PRINT
; break;
570 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
571 case GDK_Insert
: key_code
= WXK_INSERT
; break;
572 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
573 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
574 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
575 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
576 case GDK_KP_Up
: key_code
= WXK_UP
; break;
577 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
578 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
579 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
580 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
581 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
582 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
583 case GDK_KP_End
: key_code
= WXK_END
; break;
584 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
585 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
586 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
587 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
588 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
589 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
590 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
591 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
592 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
593 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
594 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
595 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
596 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
597 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
598 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
599 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
600 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
601 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
602 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
603 case GDK_F1
: key_code
= WXK_F1
; break;
604 case GDK_F2
: key_code
= WXK_F2
; break;
605 case GDK_F3
: key_code
= WXK_F3
; break;
606 case GDK_F4
: key_code
= WXK_F4
; break;
607 case GDK_F5
: key_code
= WXK_F5
; break;
608 case GDK_F6
: key_code
= WXK_F6
; break;
609 case GDK_F7
: key_code
= WXK_F7
; break;
610 case GDK_F8
: key_code
= WXK_F8
; break;
611 case GDK_F9
: key_code
= WXK_F9
; break;
612 case GDK_F10
: key_code
= WXK_F10
; break;
613 case GDK_F11
: key_code
= WXK_F11
; break;
614 case GDK_F12
: key_code
= WXK_F12
; break;
617 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
618 key_code
= gdk_event
->keyval
;
622 if (!key_code
) return FALSE
;
624 wxKeyEvent
event( wxEVT_KEY_UP
);
625 event
.SetTimestamp( gdk_event
->time
);
626 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
627 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
628 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
629 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
630 event
.m_keyCode
= key_code
;
633 event
.SetEventObject( win
);
635 if (win
->GetEventHandler()->ProcessEvent( event
))
637 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
644 //-----------------------------------------------------------------------------
645 // "button_press_event"
646 //-----------------------------------------------------------------------------
648 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
651 wxapp_install_idle_handler();
654 wxPrintf( _T("1) OnButtonPress from ") );
655 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
656 wxPrintf( win->GetClassInfo()->GetClassName() );
657 wxPrintf( _T(".\n") );
660 if (!win
->m_hasVMT
) return FALSE
;
661 if (g_blockEventsOnDrag
) return TRUE
;
662 if (g_blockEventsOnScroll
) return TRUE
;
664 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
668 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
670 gtk_widget_grab_focus (win
->m_wxwindow
);
673 wxPrintf( _T("GrabFocus from ") );
674 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
675 wxPrintf( win->GetClassInfo()->GetClassName() );
676 wxPrintf( _T(".\n") );
683 wxPrintf( _T("2) OnButtonPress from ") );
684 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
685 wxPrintf( win->GetClassInfo()->GetClassName() );
686 wxPrintf( _T(".\n") );
689 wxEventType event_type
= wxEVT_LEFT_DOWN
;
691 if (gdk_event
->button
== 1)
693 switch (gdk_event
->type
)
695 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
696 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
700 else if (gdk_event
->button
== 2)
702 switch (gdk_event
->type
)
704 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
705 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
709 else if (gdk_event
->button
== 3)
711 switch (gdk_event
->type
)
713 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
714 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
719 wxMouseEvent
event( event_type
);
720 event
.SetTimestamp( gdk_event
->time
);
721 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
722 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
723 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
724 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
725 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
726 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
727 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
729 event
.m_x
= (long)gdk_event
->x
;
730 event
.m_y
= (long)gdk_event
->y
;
732 // Some control don't have their own X window and thus cannot get
737 wxNode
*node
= win
->GetChildren().First();
740 wxWindow
*child
= (wxWindow
*)node
->Data();
742 if (child
->m_isStaticBox
)
744 // wxStaticBox is transparent in the box itself
747 int xx1
= child
->m_x
;
748 int yy1
= child
->m_y
;
749 int xx2
= child
->m_x
+ child
->m_width
;
750 int yy2
= child
->m_x
+ child
->m_height
;
753 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
755 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
757 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
759 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
762 event
.m_x
-= child
->m_x
;
763 event
.m_y
-= child
->m_y
;
770 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
771 (child
->m_x
<= event
.m_x
) &&
772 (child
->m_y
<= event
.m_y
) &&
773 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
774 (child
->m_y
+child
->m_height
>= event
.m_y
))
777 event
.m_x
-= child
->m_x
;
778 event
.m_y
-= child
->m_y
;
786 event
.SetEventObject( win
);
788 gs_timeLastClick
= gdk_event
->time
;
790 if (win
->GetEventHandler()->ProcessEvent( event
))
792 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
799 //-----------------------------------------------------------------------------
800 // "button_release_event"
801 //-----------------------------------------------------------------------------
803 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
806 wxapp_install_idle_handler();
808 if (!win
->m_hasVMT
) return FALSE
;
809 if (g_blockEventsOnDrag
) return FALSE
;
810 if (g_blockEventsOnScroll
) return FALSE
;
812 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
815 printf( "OnButtonRelease from " );
816 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
817 printf( win->GetClassInfo()->GetClassName() );
821 wxEventType event_type
= wxEVT_NULL
;
823 switch (gdk_event
->button
)
825 case 1: event_type
= wxEVT_LEFT_UP
; break;
826 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
827 case 3: event_type
= wxEVT_RIGHT_UP
; break;
830 wxMouseEvent
event( event_type
);
831 event
.SetTimestamp( gdk_event
->time
);
832 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
833 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
834 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
835 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
836 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
837 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
838 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
839 event
.m_x
= (long)gdk_event
->x
;
840 event
.m_y
= (long)gdk_event
->y
;
842 // Some control don't have their own X window and thus cannot get
847 wxNode
*node
= win
->GetChildren().First();
850 wxWindow
*child
= (wxWindow
*)node
->Data();
852 if (child
->m_isStaticBox
)
854 // wxStaticBox is transparent in the box itself
857 int xx1
= child
->m_x
;
858 int yy1
= child
->m_y
;
859 int xx2
= child
->m_x
+ child
->m_width
;
860 int yy2
= child
->m_x
+ child
->m_height
;
863 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
865 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
867 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
869 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
872 event
.m_x
-= child
->m_x
;
873 event
.m_y
-= child
->m_y
;
880 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
881 (child
->m_x
<= event
.m_x
) &&
882 (child
->m_y
<= event
.m_y
) &&
883 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
884 (child
->m_y
+child
->m_height
>= event
.m_y
))
887 event
.m_x
-= child
->m_x
;
888 event
.m_y
-= child
->m_y
;
896 event
.SetEventObject( win
);
898 if (win
->GetEventHandler()->ProcessEvent( event
))
900 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
907 //-----------------------------------------------------------------------------
908 // "motion_notify_event"
909 //-----------------------------------------------------------------------------
911 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
914 wxapp_install_idle_handler();
916 if (!win
->m_hasVMT
) return FALSE
;
917 if (g_blockEventsOnDrag
) return FALSE
;
918 if (g_blockEventsOnScroll
) return FALSE
;
920 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
922 if (gdk_event
->is_hint
)
926 GdkModifierType state
;
927 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
930 gdk_event
->state
= state
;
934 printf( "OnMotion from " );
935 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
936 printf( win->GetClassInfo()->GetClassName() );
940 wxMouseEvent
event( wxEVT_MOTION
);
941 event
.SetTimestamp( gdk_event
->time
);
942 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
943 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
944 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
945 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
946 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
947 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
948 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
950 event
.m_x
= (long)gdk_event
->x
;
951 event
.m_y
= (long)gdk_event
->y
;
953 // Some control don't have their own X window and thus cannot get
958 wxNode
*node
= win
->GetChildren().First();
961 wxWindow
*child
= (wxWindow
*)node
->Data();
963 if (child
->m_isStaticBox
)
965 // wxStaticBox is transparent in the box itself
968 int xx1
= child
->m_x
;
969 int yy1
= child
->m_y
;
970 int xx2
= child
->m_x
+ child
->m_width
;
971 int yy2
= child
->m_x
+ child
->m_height
;
974 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
976 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
978 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
980 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
983 event
.m_x
-= child
->m_x
;
984 event
.m_y
-= child
->m_y
;
991 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
992 (child
->m_x
<= event
.m_x
) &&
993 (child
->m_y
<= event
.m_y
) &&
994 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
995 (child
->m_y
+child
->m_height
>= event
.m_y
))
998 event
.m_x
-= child
->m_x
;
999 event
.m_y
-= child
->m_y
;
1003 node
= node
->Next();
1007 event
.SetEventObject( win
);
1009 if (win
->GetEventHandler()->ProcessEvent( event
))
1011 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1018 //-----------------------------------------------------------------------------
1020 //-----------------------------------------------------------------------------
1022 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1025 wxapp_install_idle_handler();
1027 if (!win
->m_hasVMT
) return FALSE
;
1028 if (g_blockEventsOnDrag
) return FALSE
;
1030 g_focusWindow
= win
;
1032 if (win
->m_wxwindow
)
1034 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1036 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1038 printf( "SetFocus flag from " );
1039 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1040 printf( win->GetClassInfo()->GetClassName() );
1048 printf( "OnSetFocus from " );
1049 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1050 printf( win->GetClassInfo()->GetClassName() );
1052 printf( WXSTRINGCAST win->GetLabel() );
1056 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1057 event
.SetEventObject( win
);
1059 if (win
->GetEventHandler()->ProcessEvent( event
))
1061 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1068 //-----------------------------------------------------------------------------
1069 // "focus_out_event"
1070 //-----------------------------------------------------------------------------
1072 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1075 wxapp_install_idle_handler();
1077 if (!win
->m_hasVMT
) return FALSE
;
1078 if (g_blockEventsOnDrag
) return FALSE
;
1080 if (win
->m_wxwindow
)
1082 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1083 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1087 printf( "OnKillFocus from " );
1088 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1089 printf( win->GetClassInfo()->GetClassName() );
1093 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1094 event
.SetEventObject( win
);
1096 if (win
->GetEventHandler()->ProcessEvent( event
))
1098 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1105 //-----------------------------------------------------------------------------
1106 // "enter_notify_event"
1107 //-----------------------------------------------------------------------------
1109 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1112 wxapp_install_idle_handler();
1114 if (!win
->m_hasVMT
) return FALSE
;
1115 if (g_blockEventsOnDrag
) return FALSE
;
1117 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1119 if (widget
->window
&& win
->GetCursor().Ok() )
1120 gdk_window_set_cursor( widget
->window
, win
->GetCursor().GetCursor() );
1122 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1123 event
.SetTimestamp( gdk_event
->time
);
1124 event
.SetEventObject( win
);
1128 GdkModifierType state
= (GdkModifierType
)0;
1130 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1132 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1133 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1134 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1135 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1136 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1137 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1138 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1140 event
.m_x
= (long)x
;
1141 event
.m_y
= (long)y
;
1143 if (win
->GetEventHandler()->ProcessEvent( event
))
1145 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1152 //-----------------------------------------------------------------------------
1153 // "leave_notify_event"
1154 //-----------------------------------------------------------------------------
1156 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1159 wxapp_install_idle_handler();
1161 if (!win
->m_hasVMT
) return FALSE
;
1162 if (g_blockEventsOnDrag
) return FALSE
;
1164 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1166 if (widget
->window
&& win
->GetCursor().Ok() )
1167 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1169 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1170 event
.SetTimestamp( gdk_event
->time
);
1171 event
.SetEventObject( win
);
1175 GdkModifierType state
= (GdkModifierType
)0;
1177 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1179 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1180 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1181 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1182 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1183 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1184 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1185 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1187 event
.m_x
= (long)x
;
1188 event
.m_y
= (long)y
;
1190 if (win
->GetEventHandler()->ProcessEvent( event
))
1192 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1199 //-----------------------------------------------------------------------------
1200 // "value_changed" from m_vAdjust
1201 //-----------------------------------------------------------------------------
1203 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1206 wxapp_install_idle_handler();
1208 if (g_blockEventsOnDrag
) return;
1210 if (!win
->m_hasVMT
) return;
1212 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1213 if (fabs(diff
) < 0.2) return;
1214 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1216 wxEventType command
= wxEVT_NULL
;
1218 float line_step
= win
->m_vAdjust
->step_increment
;
1219 float page_step
= win
->m_vAdjust
->page_increment
;
1221 if (win
->IsScrolling())
1223 command
= wxEVT_SCROLL_THUMBTRACK
;
1227 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1228 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1229 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1230 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1231 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1232 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1233 else command
= wxEVT_SCROLL_THUMBTRACK
;
1236 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1238 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1239 event
.SetEventObject( win
);
1240 win
->GetEventHandler()->ProcessEvent( event
);
1243 //-----------------------------------------------------------------------------
1244 // "value_changed" from m_hAdjust
1245 //-----------------------------------------------------------------------------
1247 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1250 wxapp_install_idle_handler();
1252 if (g_blockEventsOnDrag
) return;
1253 if (!win
->m_hasVMT
) return;
1255 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1256 if (fabs(diff
) < 0.2) return;
1257 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1259 wxEventType command
= wxEVT_NULL
;
1261 float line_step
= win
->m_hAdjust
->step_increment
;
1262 float page_step
= win
->m_hAdjust
->page_increment
;
1264 if (win
->IsScrolling())
1266 command
= wxEVT_SCROLL_THUMBTRACK
;
1270 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1271 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1272 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1273 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1274 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1275 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1276 else command
= wxEVT_SCROLL_THUMBTRACK
;
1279 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1281 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1282 event
.SetEventObject( win
);
1283 win
->GetEventHandler()->ProcessEvent( event
);
1286 //-----------------------------------------------------------------------------
1287 // "changed" from m_vAdjust
1288 //-----------------------------------------------------------------------------
1290 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1293 wxapp_install_idle_handler();
1295 if (g_blockEventsOnDrag
) return;
1296 if (!win
->m_hasVMT
) return;
1298 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1299 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1301 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1302 event
.SetEventObject( win
);
1303 win
->GetEventHandler()->ProcessEvent( event
);
1306 //-----------------------------------------------------------------------------
1307 // "changed" from m_hAdjust
1308 //-----------------------------------------------------------------------------
1310 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1313 wxapp_install_idle_handler();
1315 if (g_blockEventsOnDrag
) return;
1316 if (!win
->m_hasVMT
) return;
1318 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1319 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1321 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1322 event
.SetEventObject( win
);
1323 win
->GetEventHandler()->ProcessEvent( event
);
1326 //-----------------------------------------------------------------------------
1327 // "button_press_event" from scrollbar
1328 //-----------------------------------------------------------------------------
1330 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1331 GdkEventButton
*WXUNUSED(gdk_event
),
1335 wxapp_install_idle_handler();
1337 // don't test here as we can release the mouse while being over
1338 // a different window then the slider
1340 // if (gdk_event->window != widget->slider) return FALSE;
1342 win
->SetScrolling( TRUE
);
1347 //-----------------------------------------------------------------------------
1348 // "button_release_event" from scrollbar
1349 //-----------------------------------------------------------------------------
1351 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1352 GdkEventButton
*WXUNUSED(gdk_event
),
1356 // don't test here as we can release the mouse while being over
1357 // a different window then the slider
1359 // if (gdk_event->window != widget->slider) return FALSE;
1361 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1363 if (widget
== GTK_RANGE(scrolledWindow
->vscrollbar
))
1364 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1366 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1368 win
->SetScrolling( FALSE
);
1373 // ----------------------------------------------------------------------------
1374 // this wxWindowBase function is implemented here (in platform-specific file)
1375 // because it is static and so couldn't be made virtual
1376 // ----------------------------------------------------------------------------
1378 wxWindow
*wxWindowBase::FindFocus()
1380 return g_focusWindow
;
1383 //-----------------------------------------------------------------------------
1384 // "realize" from m_widget
1385 //-----------------------------------------------------------------------------
1387 /* we cannot set colours, fonts and cursors before the widget has
1388 been realized, so we do this directly after realization */
1391 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1394 wxapp_install_idle_handler();
1396 if (win
->m_delayedFont
)
1397 win
->SetFont( win
->GetFont() );
1399 if (win
->m_delayedBackgroundColour
)
1400 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1402 if (win
->m_delayedForegroundColour
)
1403 win
->SetForegroundColour( win
->GetForegroundColour() );
1405 win
->SetCursor( win
->GetCursor() );
1410 //-----------------------------------------------------------------------------
1411 // InsertChild for wxWindow.
1412 //-----------------------------------------------------------------------------
1414 /* Callback for wxWindow. This very strange beast has to be used because
1415 * C++ has no virtual methods in a constructor. We have to emulate a
1416 * virtual function here as wxNotebook requires a different way to insert
1417 * a child in it. I had opted for creating a wxNotebookPage window class
1418 * which would have made this superfluous (such in the MDI window system),
1419 * but no-one was listening to me... */
1421 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1423 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1424 GTK_WIDGET(child
->m_widget
),
1430 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1432 /* we now allow a window to get the focus as long as it
1433 doesn't have any children. */
1434 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1438 //-----------------------------------------------------------------------------
1440 //-----------------------------------------------------------------------------
1442 wxWindow
* wxGetActiveWindow()
1444 return g_focusWindow
;
1447 //-----------------------------------------------------------------------------
1449 //-----------------------------------------------------------------------------
1451 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1453 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
)
1454 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1457 void wxWindow::Init()
1463 m_widget
= (GtkWidget
*) NULL
;
1464 m_wxwindow
= (GtkWidget
*) NULL
;
1474 m_needParent
= TRUE
;
1475 m_isBeingDeleted
= FALSE
;
1477 m_hasScrolling
= FALSE
;
1478 m_isScrolling
= FALSE
;
1480 m_hAdjust
= (GtkAdjustment
*) NULL
;
1481 m_vAdjust
= (GtkAdjustment
*) NULL
;
1482 m_oldHorizontalPos
= 0.0;
1483 m_oldVerticalPos
= 0.0;
1486 m_scrollGC
= (GdkGC
*) NULL
;
1487 m_widgetStyle
= (GtkStyle
*) NULL
;
1489 m_insertCallback
= wxInsertChildInWindow
;
1491 m_isStaticBox
= FALSE
;
1492 m_acceptsFocus
= FALSE
;
1495 wxWindow::wxWindow()
1500 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1501 const wxPoint
&pos
, const wxSize
&size
,
1502 long style
, const wxString
&name
)
1506 Create( parent
, id
, pos
, size
, style
, name
);
1509 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1510 const wxPoint
&pos
, const wxSize
&size
,
1511 long style
, const wxString
&name
)
1513 PreCreation( parent
, id
, pos
, size
, style
, name
);
1515 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1516 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1519 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1522 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1525 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1526 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1529 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1530 scroll_class
->scrollbar_spacing
= 0;
1532 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1534 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1535 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1537 m_wxwindow
= gtk_myfixed_new();
1540 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1543 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1545 #if (GTK_MINOR_VERSION > 0)
1546 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1548 if (HasFlag(wxRAISED_BORDER
))
1550 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1552 else if (HasFlag(wxSUNKEN_BORDER
))
1554 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1558 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1560 #else // GTK_MINOR_VERSION == 0
1561 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1563 if (HasFlag(wxRAISED_BORDER
))
1565 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1567 else if (HasFlag(wxSUNKEN_BORDER
))
1569 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1573 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1575 #endif // GTK_MINOR_VERSION
1577 if (HasFlag(wxTAB_TRAVERSAL
))
1579 /* we now allow a window to get the focus as long as it
1580 doesn't have any children. */
1581 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1582 m_acceptsFocus
= FALSE
;
1586 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1587 m_acceptsFocus
= TRUE
;
1590 #if (GTK_MINOR_VERSION == 0)
1591 // shut the viewport up
1592 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1593 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1594 #endif // GTK_MINOR_VERSION == 0
1596 // I _really_ don't want scrollbars in the beginning
1597 m_vAdjust
->lower
= 0.0;
1598 m_vAdjust
->upper
= 1.0;
1599 m_vAdjust
->value
= 0.0;
1600 m_vAdjust
->step_increment
= 1.0;
1601 m_vAdjust
->page_increment
= 1.0;
1602 m_vAdjust
->page_size
= 5.0;
1603 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1604 m_hAdjust
->lower
= 0.0;
1605 m_hAdjust
->upper
= 1.0;
1606 m_hAdjust
->value
= 0.0;
1607 m_hAdjust
->step_increment
= 1.0;
1608 m_hAdjust
->page_increment
= 1.0;
1609 m_hAdjust
->page_size
= 5.0;
1610 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1612 // these handlers block mouse events to any window during scrolling such as
1613 // motion events and prevent GTK and wxWindows from fighting over where the
1616 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1617 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1619 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1620 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1622 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1623 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1625 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1626 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1628 // these handlers get notified when screen updates are required either when
1629 // scrolling or when the window size (and therefore scrollbar configuration)
1632 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1633 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1634 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1635 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1637 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1638 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1639 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1640 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1642 gtk_widget_show( m_wxwindow
);
1645 m_parent
->DoAddChild( this );
1654 wxWindow::~wxWindow()
1656 m_isBeingDeleted
= TRUE
;
1665 m_parent
->RemoveChild( this );
1669 gtk_style_unref( m_widgetStyle
);
1670 m_widgetStyle
= (GtkStyle
*) NULL
;
1675 gdk_gc_unref( m_scrollGC
);
1676 m_scrollGC
= (GdkGC
*) NULL
;
1681 gtk_widget_destroy( m_wxwindow
);
1682 m_wxwindow
= (GtkWidget
*) NULL
;
1687 gtk_widget_destroy( m_widget
);
1688 m_widget
= (GtkWidget
*) NULL
;
1692 void wxWindow::PreCreation( wxWindow
*parent
,
1697 const wxString
&name
)
1699 wxASSERT_MSG( !m_needParent
|| parent
, _T("Need complete parent.") );
1701 if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) )
1703 wxFAIL_MSG(_T("window creation failed"));
1706 m_width
= WidthDefault(size
.x
);
1707 m_height
= HeightDefault(size
.y
);
1712 if (!parent
) /* some reasonable defaults */
1716 m_x
= (gdk_screen_width () - m_width
) / 2;
1717 if (m_x
< 10) m_x
= 10;
1721 m_y
= (gdk_screen_height () - m_height
) / 2;
1722 if (m_y
< 10) m_y
= 10;
1727 void wxWindow::PostCreation()
1729 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1733 /* these get reported to wxWindows -> wxPaintEvent */
1734 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1735 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1737 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1738 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1740 #if (GTK_MINOR_VERSION > 0)
1741 /* these are called when the "sunken" or "raised" borders are drawn */
1742 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1743 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1745 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1746 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1750 GtkWidget
*connect_widget
= GetConnectWidget();
1752 ConnectWidget( connect_widget
);
1754 /* we cannot set colours, fonts and cursors before the widget has
1755 been realized, so we do this directly after realization */
1756 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1757 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1762 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1764 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1765 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1767 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1768 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1770 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1771 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1773 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1774 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1776 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1777 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1779 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1780 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1782 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1783 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1785 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1786 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1788 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1789 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1792 bool wxWindow::Destroy()
1794 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1798 return wxWindowBase::Destroy();
1801 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1803 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1804 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1806 if (m_resizing
) return; /* I don't like recursions */
1809 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1811 /* don't set the size for children of wxNotebook, just take the values. */
1819 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1821 if (x
!= -1) m_x
= x
;
1822 if (y
!= -1) m_y
= y
;
1823 if (width
!= -1) m_width
= width
;
1824 if (height
!= -1) m_height
= height
;
1834 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1836 if (width
== -1) m_width
= 80;
1839 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1841 if (height
== -1) m_height
= 26;
1844 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1845 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1846 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1847 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1851 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1853 /* the default button has a border around it */
1857 /* this is the result of hours of debugging: the following code
1858 means that if we have a m_wxwindow and we set the size of
1859 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
1860 automatically propagate its size down to its m_wxwindow,
1861 which is its client area. therefore, we have to tell the
1862 client area directly that it has to resize itself.
1863 this will lead to that m_widget (GtkScrolledWindow) will
1864 calculate how much size it needs for scrollbars etc and
1865 it will then call XXX_size_allocate of its child, which
1866 is m_wxwindow. m_wxwindow in turn will do the same with its
1867 children and so on. problems can arise if this happens
1868 before all the children have been realized as some widgets
1869 stupidy need to be realized during XXX_size_allocate (e.g.
1870 GtkNotebook) and they will segv if called otherwise. this
1871 emergency is tested in gtk_myfixed_size_allocate. Normally
1872 this shouldn't be needed and only gtk_widget_queue_resize()
1873 should be enough to provoke a resize at the next appropriate
1874 moment, but this seems to fail, e.g. when a wxNotebook contains
1875 a wxSplitterWindow: the splitter window's children won't
1876 show up properly resized then. */
1878 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
1883 m_height
+2*border
);
1888 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1889 event
.SetEventObject( this );
1890 GetEventHandler()->ProcessEvent( event
);
1895 void wxWindow::OnInternalIdle()
1900 void wxWindow::DoGetSize( int *width
, int *height
) const
1902 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1904 if (width
) (*width
) = m_width
;
1905 if (height
) (*height
) = m_height
;
1908 void wxWindow::DoSetClientSize( int width
, int height
)
1910 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1914 SetSize( width
, height
);
1921 if (!m_hasScrolling
)
1923 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1925 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1927 dw
+= 2 * window_class
->xthickness
;
1928 dh
+= 2 * window_class
->ythickness
;
1933 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1934 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1936 #if (GTK_MINOR_VERSION == 0)
1937 GtkWidget
*viewport
= scroll_window
->viewport
;
1938 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1940 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1942 dw
+= 2 * viewport_class
->xthickness
;
1943 dh
+= 2 * viewport_class
->ythickness
;
1948 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1949 GtkWidget *vscrollbar = scroll_window->vscrollbar;
1951 we use this instead: range.slider_width = 11 + 2*2pts edge
1954 if (scroll_window
->vscrollbar_visible
)
1956 dw
+= 15; /* dw += vscrollbar->allocation.width; */
1957 dw
+= scroll_class
->scrollbar_spacing
;
1960 if (scroll_window
->hscrollbar_visible
)
1962 dh
+= 15; /* dh += hscrollbar->allocation.height; */
1963 dw
+= scroll_class
->scrollbar_spacing
;
1967 SetSize( width
+dw
, height
+dh
);
1971 void wxWindow::DoGetClientSize( int *width
, int *height
) const
1973 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1977 if (width
) (*width
) = m_width
;
1978 if (height
) (*height
) = m_height
;
1985 if (!m_hasScrolling
)
1987 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1989 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
1991 dw
+= 2 * window_class
->xthickness
;
1992 dh
+= 2 * window_class
->ythickness
;
1997 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1998 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2000 #if (GTK_MINOR_VERSION == 0)
2001 GtkWidget
*viewport
= scroll_window
->viewport
;
2002 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2004 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) )
2006 dw
+= 2 * viewport_class
->xthickness
;
2007 dh
+= 2 * viewport_class
->ythickness
;
2011 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2012 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2014 we use this instead: range.slider_width = 11 + 2*2pts edge
2017 if (scroll_window
->vscrollbar_visible
)
2019 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2020 dw
+= scroll_class
->scrollbar_spacing
;
2023 if (scroll_window
->hscrollbar_visible
)
2025 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2026 dh
+= scroll_class
->scrollbar_spacing
;
2030 if (width
) (*width
) = m_width
- dw
;
2031 if (height
) (*height
) = m_height
- dh
;
2035 void wxWindow::DoGetPosition( int *x
, int *y
) const
2037 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2043 void wxWindow::ClientToScreen( int *x
, int *y
) const
2045 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2047 if (!m_widget
->window
) return;
2049 GdkWindow
*source
= (GdkWindow
*) NULL
;
2051 source
= m_wxwindow
->window
;
2053 source
= m_widget
->window
;
2057 gdk_window_get_origin( source
, &org_x
, &org_y
);
2061 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2063 org_x
+= m_widget
->allocation
.x
;
2064 org_y
+= m_widget
->allocation
.y
;
2072 void wxWindow::ScreenToClient( int *x
, int *y
) const
2074 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2076 if (!m_widget
->window
) return;
2078 GdkWindow
*source
= (GdkWindow
*) NULL
;
2080 source
= m_wxwindow
->window
;
2082 source
= m_widget
->window
;
2086 gdk_window_get_origin( source
, &org_x
, &org_y
);
2090 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2092 org_x
+= m_widget
->allocation
.x
;
2093 org_y
+= m_widget
->allocation
.y
;
2101 bool wxWindow::Show( bool show
)
2103 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2105 if (!wxWindowBase::Show(show
))
2112 gtk_widget_show( m_widget
);
2114 gtk_widget_hide( m_widget
);
2119 bool wxWindow::Enable( bool enable
)
2121 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2123 if (!wxWindowBase::Enable(enable
))
2129 gtk_widget_set_sensitive( m_widget
, enable
);
2131 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2136 int wxWindow::GetCharHeight() const
2138 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2140 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2142 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2144 return font
->ascent
+ font
->descent
;
2147 int wxWindow::GetCharWidth() const
2149 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2151 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2153 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2155 return gdk_string_width( font
, "H" );
2158 void wxWindow::GetTextExtent( const wxString
& string
,
2162 int *externalLeading
,
2163 const wxFont
*theFont
) const
2165 wxFont fontToUse
= m_font
;
2166 if (theFont
) fontToUse
= *theFont
;
2168 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2170 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2171 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2172 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2173 if (descent
) (*descent
) = font
->descent
;
2174 if (externalLeading
) (*externalLeading
) = 0; // ??
2177 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2179 event
.SetEventType( wxEVT_CHAR
);
2181 if (!GetEventHandler()->ProcessEvent( event
))
2187 void wxWindow::SetFocus()
2189 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2191 GtkWidget
*connect_widget
= GetConnectWidget();
2194 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2196 gtk_widget_grab_focus (connect_widget
);
2198 else if (GTK_IS_CONTAINER(connect_widget
))
2200 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2208 bool wxWindow::AcceptsFocus() const
2210 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2213 bool wxWindow::Reparent( wxWindow
*newParent
)
2215 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2217 gtk_widget_unparent( m_widget
);
2219 if ( !wxWindowBase::Reparent(newParent
) )
2225 void wxWindow::Raise()
2227 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2229 if (!m_widget
->window
) return;
2231 gdk_window_raise( m_widget
->window
);
2234 void wxWindow::Lower()
2236 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2238 if (!m_widget
->window
) return;
2240 gdk_window_lower( m_widget
->window
);
2243 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2245 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2247 if (!wxWindowBase::SetCursor(cursor
))
2249 // don't leave if the GTK widget has just
2251 if (!m_delayedCursor
) return FALSE
;
2254 GtkWidget
*connect_widget
= GetConnectWidget();
2255 if (!connect_widget
->window
)
2257 // indicate that a new style has been set
2258 // but it couldn't get applied as the
2259 // widget hasn't been realized yet.
2260 m_delayedCursor
= TRUE
;
2262 // pretend we have done something
2266 if ((m_widget
) && (m_widget
->window
))
2267 gdk_window_set_cursor( m_widget
->window
, GetCursor().GetCursor() );
2269 if ((m_wxwindow
) && (m_wxwindow
->window
))
2270 gdk_window_set_cursor( m_wxwindow
->window
, GetCursor().GetCursor() );
2276 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2281 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2283 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2285 if (!m_widget
->window
) return;
2287 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2291 gdk_window_clear_area( m_wxwindow
->window
,
2293 rect
->width
, rect
->height
);
2297 gdk_window_clear( m_wxwindow
->window
);
2304 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2306 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2310 GdkRectangle gdk_rect
;
2311 gdk_rect
.x
= rect
->x
;
2312 gdk_rect
.y
= rect
->y
;
2313 gdk_rect
.width
= rect
->width
;
2314 gdk_rect
.height
= rect
->height
;
2317 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2319 gtk_widget_draw( m_widget
, &gdk_rect
);
2323 void wxWindow::Clear()
2325 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2327 if (!m_widget
->window
) return;
2329 if (m_wxwindow
&& m_wxwindow
->window
)
2331 gdk_window_clear( m_wxwindow
->window
);
2336 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2338 wxWindowBase::DoSetToolTip(tip
);
2341 m_tooltip
->Apply( this );
2344 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2346 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2348 #endif // wxUSE_TOOLTIPS
2350 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2352 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2354 if (!wxWindowBase::SetBackgroundColour(colour
))
2356 // don't leave if the GTK widget has just
2358 if (!m_delayedBackgroundColour
) return FALSE
;
2361 GtkWidget
*connect_widget
= GetConnectWidget();
2362 if (!connect_widget
->window
)
2364 // indicate that a new style has been set
2365 // but it couldn't get applied as the
2366 // widget hasn't been realized yet.
2367 m_delayedBackgroundColour
= TRUE
;
2369 // pretend we have done something
2373 if (m_wxwindow
&& m_wxwindow
->window
)
2375 /* wxMSW doesn't clear the window here. I don't do that either to
2376 provide compatibility. call Clear() to do the job. */
2378 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2379 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2382 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2384 if (sysbg
== m_backgroundColour
)
2386 m_backgroundColour
= wxNullColour
;
2388 m_backgroundColour
= sysbg
;
2398 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2400 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2402 if (!wxWindowBase::SetForegroundColour(colour
))
2404 // don't leave if the GTK widget has just
2406 if (!m_delayedForegroundColour
) return FALSE
;
2409 GtkWidget
*connect_widget
= GetConnectWidget();
2410 if (!connect_widget
->window
)
2412 // indicate that a new style has been set
2413 // but it couldn't get applied as the
2414 // widget hasn't been realized yet.
2415 m_delayedForegroundColour
= TRUE
;
2417 // pretend we have done something
2421 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2422 if (sysbg
== m_foregroundColour
)
2424 m_backgroundColour
= wxNullColour
;
2426 m_backgroundColour
= sysbg
;
2436 GtkStyle
*wxWindow::GetWidgetStyle()
2438 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2440 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2442 return m_widgetStyle
;
2445 void wxWindow::SetWidgetStyle()
2447 GtkStyle
*style
= GetWidgetStyle();
2449 gdk_font_unref( style
->font
);
2450 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2452 if (m_foregroundColour
.Ok())
2454 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2455 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2456 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2457 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2460 if (m_backgroundColour
.Ok())
2462 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2463 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2464 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2465 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2466 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2467 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2468 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2469 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2470 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2474 void wxWindow::ApplyWidgetStyle()
2478 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2480 menu
->SetInvokingWindow( win
);
2481 wxNode
*node
= menu
->GetItems().First();
2484 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2485 if (menuitem
->IsSubMenu())
2487 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2489 node
= node
->Next();
2493 static gint gs_pop_x
= 0;
2494 static gint gs_pop_y
= 0;
2496 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2500 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2505 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2507 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2509 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2511 SetInvokingWindow( menu
, this );
2519 GTK_MENU(menu
->m_menu
),
2520 (GtkWidget
*) NULL
, // parent menu shell
2521 (GtkWidget
*) NULL
, // parent menu item
2522 (GtkMenuPositionFunc
) pop_pos_callback
,
2523 (gpointer
) this, // client data
2524 0, // button used to activate it
2525 0 //gs_timeLastClick // the time of activation
2530 #if wxUSE_DRAG_AND_DROP
2532 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2534 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2536 GtkWidget
*dnd_widget
= GetConnectWidget();
2538 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2540 if (m_dropTarget
) delete m_dropTarget
;
2541 m_dropTarget
= dropTarget
;
2543 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2546 #endif // wxUSE_DRAG_AND_DROP
2548 GtkWidget
* wxWindow::GetConnectWidget()
2550 GtkWidget
*connect_widget
= m_widget
;
2551 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2553 return connect_widget
;
2556 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2558 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2559 return (window
== m_widget
->window
);
2562 bool wxWindow::SetFont( const wxFont
&font
)
2564 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T( "invalid window") );
2566 if (!wxWindowBase::SetFont(font
))
2568 // don't leave if the GTK widget has just
2570 if (!m_delayedFont
) return FALSE
;
2573 GtkWidget
*connect_widget
= GetConnectWidget();
2574 if (!connect_widget
->window
)
2576 // indicate that a new style has been set
2577 // but it couldn't get applied as the
2578 // widget hasn't been realized yet.
2579 m_delayedFont
= TRUE
;
2581 // pretend we have done something
2585 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2586 if ( sysbg
== m_backgroundColour
)
2588 m_backgroundColour
= wxNullColour
;
2590 m_backgroundColour
= sysbg
;
2600 void wxWindow::CaptureMouse()
2602 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2604 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
2606 GtkWidget
*connect_widget
= GetConnectWidget();
2607 if (!connect_widget
->window
) return;
2609 gtk_grab_add( connect_widget
);
2610 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2612 (GDK_BUTTON_PRESS_MASK
|
2613 GDK_BUTTON_RELEASE_MASK
|
2614 GDK_POINTER_MOTION_MASK
),
2621 void wxWindow::ReleaseMouse()
2623 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2625 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
2627 GtkWidget
*connect_widget
= GetConnectWidget();
2628 if (!connect_widget
->window
) return;
2630 gtk_grab_remove( connect_widget
);
2631 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2632 g_capturing
= FALSE
;
2635 bool wxWindow::IsRetained() const
2640 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2641 int range
, bool refresh
)
2643 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2645 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2647 m_hasScrolling
= TRUE
;
2649 if (orient
== wxHORIZONTAL
)
2651 float fpos
= (float)pos
;
2652 float frange
= (float)range
;
2653 float fthumb
= (float)thumbVisible
;
2654 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2655 if (fpos
< 0.0) fpos
= 0.0;
2657 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2658 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2660 SetScrollPos( orient
, pos
, refresh
);
2664 m_oldHorizontalPos
= fpos
;
2666 m_hAdjust
->lower
= 0.0;
2667 m_hAdjust
->upper
= frange
;
2668 m_hAdjust
->value
= fpos
;
2669 m_hAdjust
->step_increment
= 1.0;
2670 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2671 m_hAdjust
->page_size
= fthumb
;
2675 float fpos
= (float)pos
;
2676 float frange
= (float)range
;
2677 float fthumb
= (float)thumbVisible
;
2678 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2679 if (fpos
< 0.0) fpos
= 0.0;
2681 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2682 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2684 SetScrollPos( orient
, pos
, refresh
);
2688 m_oldVerticalPos
= fpos
;
2690 m_vAdjust
->lower
= 0.0;
2691 m_vAdjust
->upper
= frange
;
2692 m_vAdjust
->value
= fpos
;
2693 m_vAdjust
->step_increment
= 1.0;
2694 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2695 m_vAdjust
->page_size
= fthumb
;
2698 if (orient
== wxHORIZONTAL
)
2699 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2701 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2704 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2706 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2708 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2710 if (orient
== wxHORIZONTAL
)
2712 float fpos
= (float)pos
;
2713 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2714 if (fpos
< 0.0) fpos
= 0.0;
2715 m_oldHorizontalPos
= fpos
;
2717 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2718 m_hAdjust
->value
= fpos
;
2722 float fpos
= (float)pos
;
2723 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2724 if (fpos
< 0.0) fpos
= 0.0;
2725 m_oldVerticalPos
= fpos
;
2727 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2728 m_vAdjust
->value
= fpos
;
2731 if (!m_isScrolling
) /* prevent recursion */
2733 if (m_wxwindow
->window
)
2735 if (orient
== wxHORIZONTAL
)
2736 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2738 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2743 int wxWindow::GetScrollThumb( int orient
) const
2745 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2747 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2749 if (orient
== wxHORIZONTAL
)
2750 return (int)(m_hAdjust
->page_size
+0.5);
2752 return (int)(m_vAdjust
->page_size
+0.5);
2755 int wxWindow::GetScrollPos( int orient
) const
2757 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2759 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2761 if (orient
== wxHORIZONTAL
)
2762 return (int)(m_hAdjust
->value
+0.5);
2764 return (int)(m_vAdjust
->value
+0.5);
2767 int wxWindow::GetScrollRange( int orient
) const
2769 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2771 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2773 if (orient
== wxHORIZONTAL
)
2774 return (int)(m_hAdjust
->upper
+0.5);
2776 return (int)(m_vAdjust
->upper
+0.5);
2779 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2781 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2783 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2787 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2788 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2793 GetClientSize( &cw
, &ch
);
2794 int w
= cw
- abs(dx
);
2795 int h
= ch
- abs(dy
);
2797 if ((h
< 0) || (w
< 0))
2805 if (dx
< 0) s_x
= -dx
;
2806 if (dy
< 0) s_y
= -dy
;
2809 if (dx
> 0) d_x
= dx
;
2810 if (dy
> 0) d_y
= dy
;
2812 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2813 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2816 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2817 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2818 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2819 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2821 Refresh( TRUE
, &rect
);
2824 wxNode
*node
= m_children
.First();
2827 wxWindow
*child
= (wxWindow
*) node
->Data();
2828 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
2829 node
= node
->Next();
2833 void wxWindow::SetScrolling(bool scroll
)
2835 m_isScrolling
= g_blockEventsOnScroll
= scroll
;