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"
46 #include "wx/gtk/win_gtk.h"
48 //-----------------------------------------------------------------------------
49 // documentation on internals
50 //-----------------------------------------------------------------------------
53 I have been asked several times about writing some documentation about
54 the GTK port of wxWindows, especially its internal structures. Obviously,
55 you cannot understand wxGTK without knowing a little about the GTK, but
56 some more information about what the wxWindow, which is the base class
57 for all other window classes, does seems required as well.
59 What does wxWindow do? It contains the common interface for the following
60 jobs of its descendants:
62 1) Define the rudimentary behaviour common to all window classes, such as
63 resizing, intercepting user input (so as to make it possible to use these
64 events for special purposes in a derived class), window names etc.
66 2) Provide the possibility to contain and manage children, if the derived
67 class is allowed to contain children, which holds true for those window
68 classes which do not display a native GTK widget. To name them, these
69 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
70 work classes are a special case and are handled a bit differently from
71 the rest. The same holds true for the wxNotebook class.
73 3) Provide the possibility to draw into a client area of a window. This,
74 too, only holds true for classes that do not display a native GTK widget
77 4) Provide the entire mechanism for scrolling widgets. This actual inter-
78 face for this is usually in wxScrolledWindow, but the GTK implementation
81 5) A multitude of helper or extra methods for special purposes, such as
82 Drag'n'Drop, managing validators etc.
84 Normally one might expect, that one wxWindows window would always correspond
85 to one GTK widget. Under GTK, there is no such allround widget that has all
86 the functionality. Moreover, the GTK defines a client area as a different
87 widget from the actual widget you are handling. Last but not least some
88 special classes (e.g. wxFrame) handle different categories of widgets and
89 still have the possibility to draw something in the client area.
90 It was therefore required to write a special purpose GTK widget, that would
91 represent a client area in the sense of wxWindows capable to do the jobs
92 2), 3) and 4). I have written this class and it resides in win_gtk.c of
95 All windows must have a widget, with which they interact with other under-
96 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
97 thw wxWindow class has a member variable called m_widget which holds a
98 pointer to this widget. When the window class represents a GTK native widget,
99 this is (in most cases) the only GTK widget the class manages. E.g. the
100 wxStatitText class handles only a GtkLabel widget a pointer to which you
101 can find in m_widget (defined in wxWindow)
103 When the class has a client area for drawing into and for containing children
104 it has to handle the client area widget (of the type GtkMyFixed, defined in
105 win_gtk.c), but there could be any number of widgets, handled by a class
106 The common rule for all windows is only, that the widget that interacts with
107 the rest of GTK must be referenced in m_widget and all other widgets must be
108 children of this widget on the GTK level. The top-most widget, which also
109 represents the client area, must be in the m_wxwindow field and must be of
112 As I said, the window classes that display a GTK native widget only have
113 one widget, so in the case of e.g. the wxButton class m_widget holds a
114 pointer to a GtkButton widget. But windows with client areas (for drawing
115 and children) have a m_widget field that is a pointer to a GtkScrolled-
116 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
117 one is (in the GTK sense) a child of the GtkScrolledWindow.
119 If the m_wxwindow field is set, then all input to this widget is inter-
120 cepted and sent to the wxWindows class. If not, all input to the widget
121 that gets pointed to by m_widget gets intercepted and sent to the class.
125 //-----------------------------------------------------------------------------
127 //-----------------------------------------------------------------------------
129 extern wxList wxPendingDelete
;
130 extern bool g_blockEventsOnDrag
;
131 extern bool g_blockEventsOnScroll
;
132 static bool g_capturing
= FALSE
;
133 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
135 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
136 the last click here */
137 static guint32 gs_timeLastClick
= 0;
139 //-----------------------------------------------------------------------------
141 //-----------------------------------------------------------------------------
145 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
146 GdkEvent
*WXUNUSED(event
),
150 static bool s_done = FALSE;
153 wxLog::AddTraceMask("focus");
156 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 // key event conversion routines
187 //-----------------------------------------------------------------------------
189 static long map_to_unmodified_wx_keysym( KeySym keysym
)
196 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
198 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
199 case GDK_Menu
: key_code
= WXK_MENU
; break;
200 case GDK_Help
: key_code
= WXK_HELP
; break;
201 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
202 case GDK_ISO_Left_Tab
:
203 case GDK_Tab
: key_code
= WXK_TAB
; break;
204 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
205 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
206 case GDK_Return
: key_code
= WXK_RETURN
; break;
207 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
208 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
209 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
210 case GDK_Delete
: key_code
= WXK_DELETE
; break;
211 case GDK_Home
: key_code
= WXK_HOME
; break;
212 case GDK_Left
: key_code
= WXK_LEFT
; break;
213 case GDK_Up
: key_code
= WXK_UP
; break;
214 case GDK_Right
: key_code
= WXK_RIGHT
; break;
215 case GDK_Down
: key_code
= WXK_DOWN
; break;
216 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
217 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
218 case GDK_Next
: key_code
= WXK_NEXT
; break;
219 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
220 case GDK_End
: key_code
= WXK_END
; break;
221 case GDK_Begin
: key_code
= WXK_HOME
; break;
222 case GDK_Select
: key_code
= WXK_SELECT
; break;
223 case GDK_Print
: key_code
= WXK_PRINT
; break;
224 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
225 case GDK_Insert
: key_code
= WXK_INSERT
; break;
226 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
228 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
229 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
230 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
231 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
232 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
233 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
234 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
235 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
236 case GDK_KP_8
: key_code
= WXK_NUMPAD8
; break;
237 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
238 case GDK_KP_Space
: key_code
= WXK_NUMPAD_SPACE
; break;
239 case GDK_KP_Tab
: key_code
= WXK_NUMPAD_TAB
; break;
240 case GDK_KP_Enter
: key_code
= WXK_NUMPAD_ENTER
; break;
241 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
242 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
243 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
244 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
245 case GDK_KP_Home
: key_code
= WXK_NUMPAD_HOME
; break;
246 case GDK_KP_Left
: key_code
= WXK_NUMPAD_LEFT
; break;
247 case GDK_KP_Up
: key_code
= WXK_NUMPAD_UP
; break;
248 case GDK_KP_Right
: key_code
= WXK_NUMPAD_RIGHT
; break;
249 case GDK_KP_Down
: key_code
= WXK_NUMPAD_DOWN
; break;
250 case GDK_KP_Prior
: key_code
= WXK_NUMPAD_PRIOR
; break;
251 // case GDK_KP_Page_Up: key_code = WXK_NUMPAD_PAGEUP; break;
252 case GDK_KP_Next
: key_code
= WXK_NUMPAD_PRIOR
; break;
253 // case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break;
254 case GDK_KP_End
: key_code
= WXK_NUMPAD_END
; break;
255 case GDK_KP_Begin
: key_code
= WXK_NUMPAD_BEGIN
; break;
256 case GDK_KP_Insert
: key_code
= WXK_NUMPAD_INSERT
; break;
257 case GDK_KP_Delete
: key_code
= WXK_NUMPAD_DELETE
; break;
258 case GDK_KP_Equal
: key_code
= WXK_NUMPAD_EQUAL
; break;
259 case GDK_KP_Multiply
: key_code
= WXK_NUMPAD_MULTIPLY
; break;
260 case GDK_KP_Add
: key_code
= WXK_NUMPAD_ADD
; break;
261 case GDK_KP_Separator
: key_code
= WXK_NUMPAD_SEPARATOR
; break;
262 case GDK_KP_Subtract
: key_code
= WXK_NUMPAD_SUBTRACT
; break;
263 case GDK_KP_Decimal
: key_code
= WXK_NUMPAD_DECIMAL
; break;
264 case GDK_KP_Divide
: key_code
= WXK_NUMPAD_DIVIDE
; break;
266 case GDK_F1
: key_code
= WXK_F1
; break;
267 case GDK_F2
: key_code
= WXK_F2
; break;
268 case GDK_F3
: key_code
= WXK_F3
; break;
269 case GDK_F4
: key_code
= WXK_F4
; break;
270 case GDK_F5
: key_code
= WXK_F5
; break;
271 case GDK_F6
: key_code
= WXK_F6
; break;
272 case GDK_F7
: key_code
= WXK_F7
; break;
273 case GDK_F8
: key_code
= WXK_F8
; break;
274 case GDK_F9
: key_code
= WXK_F9
; break;
275 case GDK_F10
: key_code
= WXK_F10
; break;
276 case GDK_F11
: key_code
= WXK_F11
; break;
277 case GDK_F12
: key_code
= WXK_F12
; break;
282 guint upper
= gdk_keyval_to_upper( keysym
);
283 keysym
= (upper
!= 0 ? upper
: keysym
); /* to be MSW compatible */
292 static long map_to_wx_keysym( KeySym keysym
)
298 case GDK_Menu
: key_code
= WXK_MENU
; break;
299 case GDK_Help
: key_code
= WXK_HELP
; break;
300 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
301 case GDK_ISO_Left_Tab
:
302 case GDK_Tab
: key_code
= WXK_TAB
; break;
303 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
304 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
305 case GDK_Return
: key_code
= WXK_RETURN
; break;
306 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
307 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
308 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
309 case GDK_Delete
: key_code
= WXK_DELETE
; break;
310 case GDK_Home
: key_code
= WXK_HOME
; break;
311 case GDK_Left
: key_code
= WXK_LEFT
; break;
312 case GDK_Up
: key_code
= WXK_UP
; break;
313 case GDK_Right
: key_code
= WXK_RIGHT
; break;
314 case GDK_Down
: key_code
= WXK_DOWN
; break;
315 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
316 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
317 case GDK_Next
: key_code
= WXK_NEXT
; break;
318 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
319 case GDK_End
: key_code
= WXK_END
; break;
320 case GDK_Begin
: key_code
= WXK_HOME
; break;
321 case GDK_Select
: key_code
= WXK_SELECT
; break;
322 case GDK_Print
: key_code
= WXK_PRINT
; break;
323 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
324 case GDK_Insert
: key_code
= WXK_INSERT
; break;
325 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
327 case GDK_KP_0
: key_code
= '0'; break;
328 case GDK_KP_1
: key_code
= '1'; break;
329 case GDK_KP_2
: key_code
= '2'; break;
330 case GDK_KP_3
: key_code
= '3'; break;
331 case GDK_KP_4
: key_code
= '4'; break;
332 case GDK_KP_5
: key_code
= '5'; break;
333 case GDK_KP_6
: key_code
= '6'; break;
334 case GDK_KP_7
: key_code
= '7'; break;
335 case GDK_KP_8
: key_code
= '8'; break;
336 case GDK_KP_9
: key_code
= '9'; break;
337 case GDK_KP_Space
: key_code
= ' '; break;
338 case GDK_KP_Tab
: key_code
= WXK_TAB
; break; /* or '\t' ??? */
339 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break; /* or '\r' ??? */
340 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
341 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
342 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
343 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
344 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
345 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
346 case GDK_KP_Up
: key_code
= WXK_UP
; break;
347 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
348 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
349 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
350 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
351 case GDK_KP_Next
: key_code
= WXK_PRIOR
; break;
352 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
353 case GDK_KP_End
: key_code
= WXK_END
; break;
354 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
355 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
356 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
357 case GDK_KP_Equal
: key_code
= '='; break;
358 case GDK_KP_Multiply
: key_code
= '*'; break;
359 case GDK_KP_Add
: key_code
= '+'; break;
360 case GDK_KP_Separator
: key_code
= ','; break;
361 case GDK_KP_Subtract
: key_code
= '-'; break;
362 case GDK_KP_Decimal
: key_code
= '.'; break;
363 case GDK_KP_Divide
: key_code
= '/'; break;
365 case GDK_F1
: key_code
= WXK_F1
; break;
366 case GDK_F2
: key_code
= WXK_F2
; break;
367 case GDK_F3
: key_code
= WXK_F3
; break;
368 case GDK_F4
: key_code
= WXK_F4
; break;
369 case GDK_F5
: key_code
= WXK_F5
; break;
370 case GDK_F6
: key_code
= WXK_F6
; break;
371 case GDK_F7
: key_code
= WXK_F7
; break;
372 case GDK_F8
: key_code
= WXK_F8
; break;
373 case GDK_F9
: key_code
= WXK_F9
; break;
374 case GDK_F10
: key_code
= WXK_F10
; break;
375 case GDK_F11
: key_code
= WXK_F11
; break;
376 case GDK_F12
: key_code
= WXK_F12
; break;
389 static long get_unmodified_wx_keysym( GdkEventKey
*event
)
391 KeyCode keycode
= XKeysymToKeycode( GDK_DISPLAY(), event
->keyval
);
392 KeySym keysym
= XKeycodeToKeysym( GDK_DISPLAY(), keycode
, 0 );
394 return (map_to_unmodified_wx_keysym( keysym
));
397 //-----------------------------------------------------------------------------
398 // local code (see below)
399 //-----------------------------------------------------------------------------
401 #if (GTK_MINOR_VERSION > 0)
403 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
411 if (win
->HasScrolling())
413 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
414 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
417 GtkWidget *hscrollbar = scroll_window->hscrollbar;
418 GtkWidget *vscrollbar = scroll_window->vscrollbar;
420 we use this instead: range.slider_width = 11 + 2*2pts edge
423 if (scroll_window
->vscrollbar_visible
)
425 dw
+= 15; /* dw += vscrollbar->allocation.width; */
426 dw
+= scroll_class
->scrollbar_spacing
;
429 if (scroll_window
->hscrollbar_visible
)
431 dh
+= 15; /* dh += hscrollbar->allocation.height; */
432 dw
+= scroll_class
->scrollbar_spacing
;
438 if (GTK_WIDGET_NO_WINDOW (widget
))
440 dx
+= widget
->allocation
.x
;
441 dy
+= widget
->allocation
.y
;
444 if (win
->HasFlag(wxRAISED_BORDER
))
446 gtk_draw_shadow( widget
->style
,
451 win
->m_width
-dw
, win
->m_height
-dh
);
455 if (win
->HasFlag(wxSUNKEN_BORDER
))
457 gtk_draw_shadow( widget
->style
,
462 win
->m_width
-dw
, win
->m_height
-dh
);
467 //-----------------------------------------------------------------------------
468 // "expose_event" of m_widget
469 //-----------------------------------------------------------------------------
471 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
473 if (gdk_event
->count
> 0) return;
474 draw_frame( widget
, win
);
477 //-----------------------------------------------------------------------------
478 // "draw" of m_wxwindow
479 //-----------------------------------------------------------------------------
481 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
483 draw_frame( widget
, win
);
486 #endif // GTK_MINOR_VERSION > 0
488 //-----------------------------------------------------------------------------
489 // "expose_event" of m_wxwindow
490 //-----------------------------------------------------------------------------
492 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
494 if ( !win
->m_hasVMT
)
497 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
499 gdk_event
->area
.width
,
500 gdk_event
->area
.height
);
502 if ( gdk_event
->count
> 0 )
506 printf( "OnExpose from " );
507 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
508 printf( win->GetClassInfo()->GetClassName() );
512 wxPaintEvent
event( win
->GetId() );
513 event
.SetEventObject( win
);
514 win
->GetEventHandler()->ProcessEvent( event
);
516 win
->GetUpdateRegion().Clear();
519 //-----------------------------------------------------------------------------
520 // "draw" of m_wxwindow
521 //-----------------------------------------------------------------------------
523 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
526 wxapp_install_idle_handler();
531 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
532 rect
->width
, rect
->height
);
534 wxPaintEvent
event( win
->GetId() );
535 event
.SetEventObject( win
);
536 win
->GetEventHandler()->ProcessEvent( event
);
538 win
->GetUpdateRegion().Clear();
541 //-----------------------------------------------------------------------------
542 // "key_press_event" from any window
543 //-----------------------------------------------------------------------------
545 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
548 wxapp_install_idle_handler();
550 if (!win
->m_hasVMT
) return FALSE
;
551 if (g_blockEventsOnDrag
) return FALSE
;
554 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
555 if (gdk_event->state & GDK_SHIFT_MASK)
556 printf( "ShiftDown.\n" );
558 printf( "ShiftUp.\n" );
559 if (gdk_event->state & GDK_CONTROL_MASK)
560 printf( "ControlDown.\n" );
562 printf( "ControlUp.\n" );
568 GdkModifierType state
;
569 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
571 long key_code
= get_unmodified_wx_keysym( gdk_event
);
573 /* sending unknown key events doesn't really make sense */
574 if (key_code
== 0) return FALSE
;
578 wxKeyEvent
event( wxEVT_KEY_DOWN
);
579 event
.SetTimestamp( gdk_event
->time
);
580 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
581 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
582 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
583 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
584 event
.m_keyCode
= key_code
;
585 event
.m_scanCode
= gdk_event
->keyval
;
588 event
.SetEventObject( win
);
589 ret
= win
->GetEventHandler()->ProcessEvent( event
);
591 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
593 /* wxMSW doesn't send char events with Alt pressed */
594 if ((key_code
!= 0) &&
595 ((gdk_event
->state
& GDK_MOD1_MASK
) == 0) &&
596 ((gdk_event
->state
& GDK_MOD1_MASK
) == 0))
598 wxKeyEvent
event2( wxEVT_CHAR
);
599 event2
.SetTimestamp( gdk_event
->time
);
600 event2
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
601 event2
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
602 // event2.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
603 // event2.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
604 event2
.m_keyCode
= key_code
;
605 event2
.m_scanCode
= gdk_event
->keyval
;
608 event2
.SetEventObject( win
);
609 ret
= (ret
|| win
->GetEventHandler()->ProcessEvent( event2
));
614 wxWindow
*ancestor
= win
;
617 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
620 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
621 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
624 ancestor
= ancestor
->GetParent();
628 // win is a control: tab can be propagated up
630 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
631 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
633 wxNavigationKeyEvent new_event
;
634 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
635 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
636 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
637 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
638 new_event
.SetCurrentFocus( win
);
639 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
643 (gdk_event
->keyval
== GDK_Escape
) )
645 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
646 new_event
.SetEventObject( win
);
647 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
651 Damn, I forgot why this didn't work, but it didn't work.
653 // win is a panel: up can be propagated to the panel
654 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
655 (gdk_event->keyval == GDK_Up))
657 win->m_parent->SetFocus();
661 // win is a panel: left/right can be propagated to the panel
662 if ((!ret) && (win->m_wxwindow) &&
663 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
664 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
666 wxNavigationKeyEvent new_event;
667 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
668 new_event.SetCurrentFocus( win );
669 ret = win->GetEventHandler()->ProcessEvent( new_event );
675 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
682 //-----------------------------------------------------------------------------
683 // "key_release_event" from any window
684 //-----------------------------------------------------------------------------
686 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
689 wxapp_install_idle_handler();
691 if (!win
->m_hasVMT
) return FALSE
;
692 if (g_blockEventsOnDrag
) return FALSE
;
695 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
696 if (gdk_event->state & GDK_SHIFT_MASK)
697 printf( "ShiftDown.\n" );
699 printf( "ShiftUp.\n" );
700 if (gdk_event->state & GDK_CONTROL_MASK)
701 printf( "ControlDown.\n" );
703 printf( "ControlUp.\n" );
707 long key_code
= get_unmodified_wx_keysym( gdk_event
);
709 /* sending unknown key events doesn't really make sense */
710 if (key_code
== 0) return FALSE
;
714 GdkModifierType state
;
715 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
717 wxKeyEvent
event( wxEVT_KEY_UP
);
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_keyCode
= key_code
;
724 event
.m_scanCode
= gdk_event
->keyval
;
727 event
.SetEventObject( win
);
729 if (win
->GetEventHandler()->ProcessEvent( event
))
731 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
738 //-----------------------------------------------------------------------------
739 // "button_press_event"
740 //-----------------------------------------------------------------------------
742 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
745 wxapp_install_idle_handler();
748 wxPrintf( _T("1) OnButtonPress from ") );
749 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
750 wxPrintf( win->GetClassInfo()->GetClassName() );
751 wxPrintf( _T(".\n") );
753 if (!win
->m_hasVMT
) return FALSE
;
754 if (g_blockEventsOnDrag
) return TRUE
;
755 if (g_blockEventsOnScroll
) return TRUE
;
757 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
761 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
763 gtk_widget_grab_focus (win
->m_wxwindow
);
766 wxPrintf( _T("GrabFocus from ") );
767 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
768 wxPrintf( win->GetClassInfo()->GetClassName() );
769 wxPrintf( _T(".\n") );
776 wxPrintf( _T("2) OnButtonPress from ") );
777 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
778 wxPrintf( win->GetClassInfo()->GetClassName() );
779 wxPrintf( _T(".\n") );
782 wxEventType event_type
= wxEVT_LEFT_DOWN
;
784 if (gdk_event
->button
== 1)
786 switch (gdk_event
->type
)
788 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
789 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
793 else if (gdk_event
->button
== 2)
795 switch (gdk_event
->type
)
797 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
798 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
802 else if (gdk_event
->button
== 3)
804 switch (gdk_event
->type
)
806 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
807 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
812 wxMouseEvent
event( event_type
);
813 event
.SetTimestamp( gdk_event
->time
);
814 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
815 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
816 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
817 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
818 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
819 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
820 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
822 event
.m_x
= (long)gdk_event
->x
;
823 event
.m_y
= (long)gdk_event
->y
;
825 // Some control don't have their own X window and thus cannot get
830 wxNode
*node
= win
->GetChildren().First();
833 wxWindow
*child
= (wxWindow
*)node
->Data();
835 if (child
->m_isStaticBox
)
837 // wxStaticBox is transparent in the box itself
840 int xx1
= child
->m_x
;
841 int yy1
= child
->m_y
;
842 int xx2
= child
->m_x
+ child
->m_width
;
843 int yy2
= child
->m_x
+ child
->m_height
;
846 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
848 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
850 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
852 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
855 event
.m_x
-= child
->m_x
;
856 event
.m_y
-= child
->m_y
;
863 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
864 (child
->m_x
<= event
.m_x
) &&
865 (child
->m_y
<= event
.m_y
) &&
866 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
867 (child
->m_y
+child
->m_height
>= event
.m_y
))
870 event
.m_x
-= child
->m_x
;
871 event
.m_y
-= child
->m_y
;
879 event
.SetEventObject( win
);
881 gs_timeLastClick
= gdk_event
->time
;
883 if (win
->GetEventHandler()->ProcessEvent( event
))
885 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
892 //-----------------------------------------------------------------------------
893 // "button_release_event"
894 //-----------------------------------------------------------------------------
896 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
899 wxapp_install_idle_handler();
901 if (!win
->m_hasVMT
) return FALSE
;
902 if (g_blockEventsOnDrag
) return FALSE
;
903 if (g_blockEventsOnScroll
) return FALSE
;
905 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
908 printf( "OnButtonRelease from " );
909 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
910 printf( win->GetClassInfo()->GetClassName() );
914 wxEventType event_type
= wxEVT_NULL
;
916 switch (gdk_event
->button
)
918 case 1: event_type
= wxEVT_LEFT_UP
; break;
919 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
920 case 3: event_type
= wxEVT_RIGHT_UP
; break;
923 wxMouseEvent
event( event_type
);
924 event
.SetTimestamp( gdk_event
->time
);
925 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
926 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
927 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
928 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
929 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
930 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
931 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
932 event
.m_x
= (long)gdk_event
->x
;
933 event
.m_y
= (long)gdk_event
->y
;
935 // Some control don't have their own X window and thus cannot get
940 wxNode
*node
= win
->GetChildren().First();
943 wxWindow
*child
= (wxWindow
*)node
->Data();
945 if (child
->m_isStaticBox
)
947 // wxStaticBox is transparent in the box itself
950 int xx1
= child
->m_x
;
951 int yy1
= child
->m_y
;
952 int xx2
= child
->m_x
+ child
->m_width
;
953 int yy2
= child
->m_x
+ child
->m_height
;
956 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
958 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
960 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
962 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
965 event
.m_x
-= child
->m_x
;
966 event
.m_y
-= child
->m_y
;
973 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
974 (child
->m_x
<= event
.m_x
) &&
975 (child
->m_y
<= event
.m_y
) &&
976 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
977 (child
->m_y
+child
->m_height
>= event
.m_y
))
980 event
.m_x
-= child
->m_x
;
981 event
.m_y
-= child
->m_y
;
989 event
.SetEventObject( win
);
991 if (win
->GetEventHandler()->ProcessEvent( event
))
993 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1000 //-----------------------------------------------------------------------------
1001 // "motion_notify_event"
1002 //-----------------------------------------------------------------------------
1004 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1007 wxapp_install_idle_handler();
1009 if (!win
->m_hasVMT
) return FALSE
;
1010 if (g_blockEventsOnDrag
) return FALSE
;
1011 if (g_blockEventsOnScroll
) return FALSE
;
1013 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1015 if (gdk_event
->is_hint
)
1019 GdkModifierType state
;
1020 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1023 gdk_event
->state
= state
;
1027 printf( "OnMotion from " );
1028 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1029 printf( win->GetClassInfo()->GetClassName() );
1033 wxMouseEvent
event( wxEVT_MOTION
);
1034 event
.SetTimestamp( gdk_event
->time
);
1035 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1036 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1037 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1038 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1039 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1040 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1041 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1043 event
.m_x
= (long)gdk_event
->x
;
1044 event
.m_y
= (long)gdk_event
->y
;
1046 // Some control don't have their own X window and thus cannot get
1051 wxNode
*node
= win
->GetChildren().First();
1054 wxWindow
*child
= (wxWindow
*)node
->Data();
1056 if (child
->m_isStaticBox
)
1058 // wxStaticBox is transparent in the box itself
1061 int xx1
= child
->m_x
;
1062 int yy1
= child
->m_y
;
1063 int xx2
= child
->m_x
+ child
->m_width
;
1064 int yy2
= child
->m_x
+ child
->m_height
;
1067 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1069 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1071 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1073 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1076 event
.m_x
-= child
->m_x
;
1077 event
.m_y
-= child
->m_y
;
1084 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1085 (child
->m_x
<= event
.m_x
) &&
1086 (child
->m_y
<= event
.m_y
) &&
1087 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1088 (child
->m_y
+child
->m_height
>= event
.m_y
))
1091 event
.m_x
-= child
->m_x
;
1092 event
.m_y
-= child
->m_y
;
1096 node
= node
->Next();
1100 event
.SetEventObject( win
);
1102 if (win
->GetEventHandler()->ProcessEvent( event
))
1104 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1111 //-----------------------------------------------------------------------------
1113 //-----------------------------------------------------------------------------
1115 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1118 wxapp_install_idle_handler();
1120 if (!win
->m_hasVMT
) return FALSE
;
1121 if (g_blockEventsOnDrag
) return FALSE
;
1123 g_focusWindow
= win
;
1125 if (win
->m_wxwindow
)
1127 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1129 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1131 printf( "SetFocus flag from " );
1132 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1133 printf( win->GetClassInfo()->GetClassName() );
1141 printf( "OnSetFocus from " );
1142 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1143 printf( win->GetClassInfo()->GetClassName() );
1145 printf( WXSTRINGCAST win->GetLabel() );
1149 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1150 event
.SetEventObject( win
);
1152 if (win
->GetEventHandler()->ProcessEvent( event
))
1154 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1161 //-----------------------------------------------------------------------------
1162 // "focus_out_event"
1163 //-----------------------------------------------------------------------------
1165 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1168 wxapp_install_idle_handler();
1170 if (!win
->m_hasVMT
) return FALSE
;
1171 if (g_blockEventsOnDrag
) return FALSE
;
1173 if (win
->m_wxwindow
)
1175 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1176 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1180 printf( "OnKillFocus from " );
1181 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1182 printf( win->GetClassInfo()->GetClassName() );
1186 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1187 event
.SetEventObject( win
);
1189 if (win
->GetEventHandler()->ProcessEvent( event
))
1191 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1198 //-----------------------------------------------------------------------------
1199 // "enter_notify_event"
1200 //-----------------------------------------------------------------------------
1202 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1205 wxapp_install_idle_handler();
1207 if (!win
->m_hasVMT
) return FALSE
;
1208 if (g_blockEventsOnDrag
) return FALSE
;
1210 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1212 if (widget
->window
&& win
->GetCursor().Ok() )
1213 gdk_window_set_cursor( widget
->window
, win
->GetCursor().GetCursor() );
1215 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1216 event
.SetTimestamp( gdk_event
->time
);
1217 event
.SetEventObject( win
);
1221 GdkModifierType state
= (GdkModifierType
)0;
1223 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1225 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1226 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1227 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1228 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1229 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1230 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1231 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1233 event
.m_x
= (long)x
;
1234 event
.m_y
= (long)y
;
1236 if (win
->GetEventHandler()->ProcessEvent( event
))
1238 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1245 //-----------------------------------------------------------------------------
1246 // "leave_notify_event"
1247 //-----------------------------------------------------------------------------
1249 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1252 wxapp_install_idle_handler();
1254 if (!win
->m_hasVMT
) return FALSE
;
1255 if (g_blockEventsOnDrag
) return FALSE
;
1257 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1259 if (widget
->window
&& win
->GetCursor().Ok() )
1260 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1262 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1263 event
.SetTimestamp( gdk_event
->time
);
1264 event
.SetEventObject( win
);
1268 GdkModifierType state
= (GdkModifierType
)0;
1270 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1272 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1273 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1274 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1275 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1276 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1277 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1278 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1280 event
.m_x
= (long)x
;
1281 event
.m_y
= (long)y
;
1283 if (win
->GetEventHandler()->ProcessEvent( event
))
1285 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1292 //-----------------------------------------------------------------------------
1293 // "value_changed" from m_vAdjust
1294 //-----------------------------------------------------------------------------
1296 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1299 wxapp_install_idle_handler();
1301 if (g_blockEventsOnDrag
) return;
1303 if (!win
->m_hasVMT
) return;
1305 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1306 if (fabs(diff
) < 0.2) return;
1307 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1309 wxEventType command
= wxEVT_NULL
;
1311 float line_step
= win
->m_vAdjust
->step_increment
;
1312 float page_step
= win
->m_vAdjust
->page_increment
;
1314 if (win
->IsScrolling())
1316 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1320 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1321 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1322 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1323 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1324 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1325 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1326 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1329 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1331 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1332 event
.SetEventObject( win
);
1333 win
->GetEventHandler()->ProcessEvent( event
);
1336 //-----------------------------------------------------------------------------
1337 // "value_changed" from m_hAdjust
1338 //-----------------------------------------------------------------------------
1340 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1343 wxapp_install_idle_handler();
1345 if (g_blockEventsOnDrag
) return;
1346 if (!win
->m_hasVMT
) return;
1348 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1349 if (fabs(diff
) < 0.2) return;
1350 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1352 wxEventType command
= wxEVT_NULL
;
1354 float line_step
= win
->m_hAdjust
->step_increment
;
1355 float page_step
= win
->m_hAdjust
->page_increment
;
1357 if (win
->IsScrolling())
1359 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1363 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1364 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1365 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1366 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1367 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1368 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1369 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1372 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1374 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1375 event
.SetEventObject( win
);
1376 win
->GetEventHandler()->ProcessEvent( event
);
1379 //-----------------------------------------------------------------------------
1380 // "changed" from m_vAdjust
1381 //-----------------------------------------------------------------------------
1383 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1386 wxapp_install_idle_handler();
1388 if (g_blockEventsOnDrag
) return;
1389 if (!win
->m_hasVMT
) return;
1391 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1392 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1394 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1395 event
.SetEventObject( win
);
1396 win
->GetEventHandler()->ProcessEvent( event
);
1399 //-----------------------------------------------------------------------------
1400 // "changed" from m_hAdjust
1401 //-----------------------------------------------------------------------------
1403 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1406 wxapp_install_idle_handler();
1408 if (g_blockEventsOnDrag
) return;
1409 if (!win
->m_hasVMT
) return;
1411 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1412 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1414 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1415 event
.SetEventObject( win
);
1416 win
->GetEventHandler()->ProcessEvent( event
);
1419 //-----------------------------------------------------------------------------
1420 // "button_press_event" from scrollbar
1421 //-----------------------------------------------------------------------------
1423 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1424 GdkEventButton
*WXUNUSED(gdk_event
),
1428 wxapp_install_idle_handler();
1430 // don't test here as we can release the mouse while being over
1431 // a different window then the slider
1433 // if (gdk_event->window != widget->slider) return FALSE;
1435 win
->SetScrolling( TRUE
);
1440 //-----------------------------------------------------------------------------
1441 // "button_release_event" from scrollbar
1442 //-----------------------------------------------------------------------------
1444 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1445 GdkEventButton
*WXUNUSED(gdk_event
),
1449 // don't test here as we can release the mouse while being over
1450 // a different window then the slider
1452 // if (gdk_event->window != widget->slider) return FALSE;
1454 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1456 if (widget
== GTK_RANGE(scrolledWindow
->vscrollbar
))
1457 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1459 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1461 win
->SetScrolling( FALSE
);
1466 // ----------------------------------------------------------------------------
1467 // this wxWindowBase function is implemented here (in platform-specific file)
1468 // because it is static and so couldn't be made virtual
1469 // ----------------------------------------------------------------------------
1471 wxWindow
*wxWindowBase::FindFocus()
1473 return g_focusWindow
;
1476 //-----------------------------------------------------------------------------
1477 // "realize" from m_widget
1478 //-----------------------------------------------------------------------------
1480 /* we cannot set colours, fonts and cursors before the widget has
1481 been realized, so we do this directly after realization */
1484 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1487 wxapp_install_idle_handler();
1489 if (win
->m_delayedFont
)
1490 win
->SetFont( win
->GetFont() );
1492 if (win
->m_delayedBackgroundColour
)
1493 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1495 if (win
->m_delayedForegroundColour
)
1496 win
->SetForegroundColour( win
->GetForegroundColour() );
1498 win
->SetCursor( win
->GetCursor() );
1503 //-----------------------------------------------------------------------------
1504 // InsertChild for wxWindow.
1505 //-----------------------------------------------------------------------------
1507 /* Callback for wxWindow. This very strange beast has to be used because
1508 * C++ has no virtual methods in a constructor. We have to emulate a
1509 * virtual function here as wxNotebook requires a different way to insert
1510 * a child in it. I had opted for creating a wxNotebookPage window class
1511 * which would have made this superfluous (such in the MDI window system),
1512 * but no-one was listening to me... */
1514 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1516 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1517 GTK_WIDGET(child
->m_widget
),
1523 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1525 /* we now allow a window to get the focus as long as it
1526 doesn't have any children. */
1527 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1531 //-----------------------------------------------------------------------------
1533 //-----------------------------------------------------------------------------
1535 wxWindow
* wxGetActiveWindow()
1537 return g_focusWindow
;
1540 //-----------------------------------------------------------------------------
1542 //-----------------------------------------------------------------------------
1544 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1546 void wxWindow::Init()
1552 m_widget
= (GtkWidget
*) NULL
;
1553 m_wxwindow
= (GtkWidget
*) NULL
;
1563 m_needParent
= TRUE
;
1564 m_isBeingDeleted
= FALSE
;
1566 m_hasScrolling
= FALSE
;
1567 m_isScrolling
= FALSE
;
1569 m_hAdjust
= (GtkAdjustment
*) NULL
;
1570 m_vAdjust
= (GtkAdjustment
*) NULL
;
1571 m_oldHorizontalPos
= 0.0;
1572 m_oldVerticalPos
= 0.0;
1575 m_scrollGC
= (GdkGC
*) NULL
;
1576 m_widgetStyle
= (GtkStyle
*) NULL
;
1578 m_insertCallback
= wxInsertChildInWindow
;
1580 m_isStaticBox
= FALSE
;
1581 m_acceptsFocus
= FALSE
;
1584 wxWindow::wxWindow()
1589 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1590 const wxPoint
&pos
, const wxSize
&size
,
1591 long style
, const wxString
&name
)
1595 Create( parent
, id
, pos
, size
, style
, name
);
1598 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1599 const wxPoint
&pos
, const wxSize
&size
,
1600 long style
, const wxString
&name
)
1602 PreCreation( parent
, id
, pos
, size
, style
, name
);
1604 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1605 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1608 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1611 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1614 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1615 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1618 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1619 scroll_class
->scrollbar_spacing
= 0;
1621 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1623 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1624 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1626 m_wxwindow
= gtk_myfixed_new();
1629 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1632 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1634 #if (GTK_MINOR_VERSION > 0)
1635 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1637 if (HasFlag(wxRAISED_BORDER
))
1639 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1641 else if (HasFlag(wxSUNKEN_BORDER
))
1643 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1647 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1649 #else // GTK_MINOR_VERSION == 0
1650 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1652 if (HasFlag(wxRAISED_BORDER
))
1654 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1656 else if (HasFlag(wxSUNKEN_BORDER
))
1658 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1662 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1664 #endif // GTK_MINOR_VERSION
1666 if (HasFlag(wxTAB_TRAVERSAL
))
1668 /* we now allow a window to get the focus as long as it
1669 doesn't have any children. */
1670 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1671 m_acceptsFocus
= FALSE
;
1675 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1676 m_acceptsFocus
= TRUE
;
1679 #if (GTK_MINOR_VERSION == 0)
1680 // shut the viewport up
1681 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1682 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1683 #endif // GTK_MINOR_VERSION == 0
1685 // I _really_ don't want scrollbars in the beginning
1686 m_vAdjust
->lower
= 0.0;
1687 m_vAdjust
->upper
= 1.0;
1688 m_vAdjust
->value
= 0.0;
1689 m_vAdjust
->step_increment
= 1.0;
1690 m_vAdjust
->page_increment
= 1.0;
1691 m_vAdjust
->page_size
= 5.0;
1692 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1693 m_hAdjust
->lower
= 0.0;
1694 m_hAdjust
->upper
= 1.0;
1695 m_hAdjust
->value
= 0.0;
1696 m_hAdjust
->step_increment
= 1.0;
1697 m_hAdjust
->page_increment
= 1.0;
1698 m_hAdjust
->page_size
= 5.0;
1699 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1701 // these handlers block mouse events to any window during scrolling such as
1702 // motion events and prevent GTK and wxWindows from fighting over where the
1705 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1706 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1708 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1709 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1711 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1712 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1714 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1715 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1717 // these handlers get notified when screen updates are required either when
1718 // scrolling or when the window size (and therefore scrollbar configuration)
1721 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1722 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1723 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1724 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1726 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1727 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1728 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1729 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1731 gtk_widget_show( m_wxwindow
);
1734 m_parent
->DoAddChild( this );
1743 wxWindow::~wxWindow()
1745 m_isBeingDeleted
= TRUE
;
1754 m_parent
->RemoveChild( this );
1758 gtk_style_unref( m_widgetStyle
);
1759 m_widgetStyle
= (GtkStyle
*) NULL
;
1764 gdk_gc_unref( m_scrollGC
);
1765 m_scrollGC
= (GdkGC
*) NULL
;
1770 gtk_widget_destroy( m_wxwindow
);
1771 m_wxwindow
= (GtkWidget
*) NULL
;
1776 gtk_widget_destroy( m_widget
);
1777 m_widget
= (GtkWidget
*) NULL
;
1781 void wxWindow::PreCreation( wxWindow
*parent
,
1786 const wxString
&name
)
1788 wxASSERT_MSG( !m_needParent
|| parent
, _T("Need complete parent.") );
1790 if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) )
1792 wxFAIL_MSG(_T("window creation failed"));
1795 m_width
= WidthDefault(size
.x
);
1796 m_height
= HeightDefault(size
.y
);
1801 if (!parent
) /* some reasonable defaults */
1805 m_x
= (gdk_screen_width () - m_width
) / 2;
1806 if (m_x
< 10) m_x
= 10;
1810 m_y
= (gdk_screen_height () - m_height
) / 2;
1811 if (m_y
< 10) m_y
= 10;
1816 void wxWindow::PostCreation()
1818 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1822 /* these get reported to wxWindows -> wxPaintEvent */
1823 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1824 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1826 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1827 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1829 #if (GTK_MINOR_VERSION > 0)
1830 /* these are called when the "sunken" or "raised" borders are drawn */
1831 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1832 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1834 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1835 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1839 GtkWidget
*connect_widget
= GetConnectWidget();
1841 ConnectWidget( connect_widget
);
1843 /* we cannot set colours, fonts and cursors before the widget has
1844 been realized, so we do this directly after realization */
1845 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1846 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1851 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1853 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1854 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1856 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1857 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1859 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1860 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1862 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1863 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1865 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1866 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1868 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1869 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1871 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1872 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1874 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1875 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1877 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1878 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1881 bool wxWindow::Destroy()
1883 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1887 return wxWindowBase::Destroy();
1890 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1892 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1893 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1895 if (m_resizing
) return; /* I don't like recursions */
1898 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1900 /* don't set the size for children of wxNotebook, just take the values. */
1908 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1910 if (x
!= -1) m_x
= x
;
1911 if (y
!= -1) m_y
= y
;
1912 if (width
!= -1) m_width
= width
;
1913 if (height
!= -1) m_height
= height
;
1923 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1925 if (width
== -1) m_width
= 80;
1928 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1930 if (height
== -1) m_height
= 26;
1933 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1934 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1935 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1936 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1940 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1942 /* the default button has a border around it */
1946 /* this is the result of hours of debugging: the following code
1947 means that if we have a m_wxwindow and we set the size of
1948 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
1949 automatically propagate its size down to its m_wxwindow,
1950 which is its client area. therefore, we have to tell the
1951 client area directly that it has to resize itself.
1952 this will lead to that m_widget (GtkScrolledWindow) will
1953 calculate how much size it needs for scrollbars etc and
1954 it will then call XXX_size_allocate of its child, which
1955 is m_wxwindow. m_wxwindow in turn will do the same with its
1956 children and so on. problems can arise if this happens
1957 before all the children have been realized as some widgets
1958 stupidy need to be realized during XXX_size_allocate (e.g.
1959 GtkNotebook) and they will segv if called otherwise. this
1960 emergency is tested in gtk_myfixed_size_allocate. Normally
1961 this shouldn't be needed and only gtk_widget_queue_resize()
1962 should be enough to provoke a resize at the next appropriate
1963 moment, but this seems to fail, e.g. when a wxNotebook contains
1964 a wxSplitterWindow: the splitter window's children won't
1965 show up properly resized then. */
1967 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
1972 m_height
+2*border
);
1977 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1978 event
.SetEventObject( this );
1979 GetEventHandler()->ProcessEvent( event
);
1984 void wxWindow::OnInternalIdle()
1989 void wxWindow::DoGetSize( int *width
, int *height
) const
1991 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1993 if (width
) (*width
) = m_width
;
1994 if (height
) (*height
) = m_height
;
1997 void wxWindow::DoSetClientSize( int width
, int height
)
1999 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2003 SetSize( width
, height
);
2010 if (!m_hasScrolling
)
2012 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2014 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2016 dw
+= 2 * window_class
->xthickness
;
2017 dh
+= 2 * window_class
->ythickness
;
2022 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2023 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2025 #if (GTK_MINOR_VERSION == 0)
2026 GtkWidget
*viewport
= scroll_window
->viewport
;
2027 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2029 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2031 dw
+= 2 * viewport_class
->xthickness
;
2032 dh
+= 2 * viewport_class
->ythickness
;
2037 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2038 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2040 we use this instead: range.slider_width = 11 + 2*2pts edge
2043 if (scroll_window
->vscrollbar_visible
)
2045 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2046 dw
+= scroll_class
->scrollbar_spacing
;
2049 if (scroll_window
->hscrollbar_visible
)
2051 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2052 dw
+= scroll_class
->scrollbar_spacing
;
2056 SetSize( width
+dw
, height
+dh
);
2060 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2062 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2066 if (width
) (*width
) = m_width
;
2067 if (height
) (*height
) = m_height
;
2074 if (!m_hasScrolling
)
2076 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2078 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2080 dw
+= 2 * window_class
->xthickness
;
2081 dh
+= 2 * window_class
->ythickness
;
2086 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2087 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2089 #if (GTK_MINOR_VERSION == 0)
2090 GtkWidget
*viewport
= scroll_window
->viewport
;
2091 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2093 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) )
2095 dw
+= 2 * viewport_class
->xthickness
;
2096 dh
+= 2 * viewport_class
->ythickness
;
2100 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2101 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2103 we use this instead: range.slider_width = 11 + 2*2pts edge
2106 if (scroll_window
->vscrollbar_visible
)
2108 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2109 dw
+= scroll_class
->scrollbar_spacing
;
2112 if (scroll_window
->hscrollbar_visible
)
2114 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2115 dh
+= scroll_class
->scrollbar_spacing
;
2119 if (width
) (*width
) = m_width
- dw
;
2120 if (height
) (*height
) = m_height
- dh
;
2124 void wxWindow::DoGetPosition( int *x
, int *y
) const
2126 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2132 void wxWindow::ClientToScreen( int *x
, int *y
) const
2134 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2136 if (!m_widget
->window
) return;
2138 GdkWindow
*source
= (GdkWindow
*) NULL
;
2140 source
= m_wxwindow
->window
;
2142 source
= m_widget
->window
;
2146 gdk_window_get_origin( source
, &org_x
, &org_y
);
2150 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2152 org_x
+= m_widget
->allocation
.x
;
2153 org_y
+= m_widget
->allocation
.y
;
2161 void wxWindow::ScreenToClient( int *x
, int *y
) const
2163 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2165 if (!m_widget
->window
) return;
2167 GdkWindow
*source
= (GdkWindow
*) NULL
;
2169 source
= m_wxwindow
->window
;
2171 source
= m_widget
->window
;
2175 gdk_window_get_origin( source
, &org_x
, &org_y
);
2179 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2181 org_x
+= m_widget
->allocation
.x
;
2182 org_y
+= m_widget
->allocation
.y
;
2190 bool wxWindow::Show( bool show
)
2192 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2194 if (!wxWindowBase::Show(show
))
2201 gtk_widget_show( m_widget
);
2203 gtk_widget_hide( m_widget
);
2208 bool wxWindow::Enable( bool enable
)
2210 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2212 if (!wxWindowBase::Enable(enable
))
2218 gtk_widget_set_sensitive( m_widget
, enable
);
2220 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2225 int wxWindow::GetCharHeight() const
2227 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2229 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2231 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2233 return font
->ascent
+ font
->descent
;
2236 int wxWindow::GetCharWidth() const
2238 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2240 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2242 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2244 return gdk_string_width( font
, "H" );
2247 void wxWindow::GetTextExtent( const wxString
& string
,
2251 int *externalLeading
,
2252 const wxFont
*theFont
) const
2254 wxFont fontToUse
= m_font
;
2255 if (theFont
) fontToUse
= *theFont
;
2257 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2259 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2260 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2261 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2262 if (descent
) (*descent
) = font
->descent
;
2263 if (externalLeading
) (*externalLeading
) = 0; // ??
2266 void wxWindow::SetFocus()
2268 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2270 GtkWidget
*connect_widget
= GetConnectWidget();
2273 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2275 gtk_widget_grab_focus (connect_widget
);
2277 else if (GTK_IS_CONTAINER(connect_widget
))
2279 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2287 bool wxWindow::AcceptsFocus() const
2289 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2292 bool wxWindow::Reparent( wxWindow
*newParent
)
2294 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2296 gtk_widget_unparent( m_widget
);
2298 if ( !wxWindowBase::Reparent(newParent
) )
2304 void wxWindow::Raise()
2306 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2308 if (!m_widget
->window
) return;
2310 gdk_window_raise( m_widget
->window
);
2313 void wxWindow::Lower()
2315 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2317 if (!m_widget
->window
) return;
2319 gdk_window_lower( m_widget
->window
);
2322 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2324 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2326 if (!wxWindowBase::SetCursor(cursor
))
2328 // don't leave if the GTK widget has just
2330 if (!m_delayedCursor
) return FALSE
;
2333 GtkWidget
*connect_widget
= GetConnectWidget();
2334 if (!connect_widget
->window
)
2336 // indicate that a new style has been set
2337 // but it couldn't get applied as the
2338 // widget hasn't been realized yet.
2339 m_delayedCursor
= TRUE
;
2341 // pretend we have done something
2345 if ((m_widget
) && (m_widget
->window
))
2346 gdk_window_set_cursor( m_widget
->window
, GetCursor().GetCursor() );
2348 if ((m_wxwindow
) && (m_wxwindow
->window
))
2349 gdk_window_set_cursor( m_wxwindow
->window
, GetCursor().GetCursor() );
2355 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2360 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2362 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2364 if (!m_widget
->window
) return;
2366 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2370 gdk_window_clear_area( m_wxwindow
->window
,
2372 rect
->width
, rect
->height
);
2376 gdk_window_clear( m_wxwindow
->window
);
2383 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2385 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2389 GdkRectangle gdk_rect
;
2390 gdk_rect
.x
= rect
->x
;
2391 gdk_rect
.y
= rect
->y
;
2392 gdk_rect
.width
= rect
->width
;
2393 gdk_rect
.height
= rect
->height
;
2396 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2398 gtk_widget_draw( m_widget
, &gdk_rect
);
2402 void wxWindow::Clear()
2404 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2406 if (!m_widget
->window
) return;
2408 if (m_wxwindow
&& m_wxwindow
->window
)
2410 gdk_window_clear( m_wxwindow
->window
);
2415 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2417 wxWindowBase::DoSetToolTip(tip
);
2420 m_tooltip
->Apply( this );
2423 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2425 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2427 #endif // wxUSE_TOOLTIPS
2429 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2431 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2433 if (!wxWindowBase::SetBackgroundColour(colour
))
2435 // don't leave if the GTK widget has just
2437 if (!m_delayedBackgroundColour
) return FALSE
;
2440 GtkWidget
*connect_widget
= GetConnectWidget();
2441 if (!connect_widget
->window
)
2443 // indicate that a new style has been set
2444 // but it couldn't get applied as the
2445 // widget hasn't been realized yet.
2446 m_delayedBackgroundColour
= TRUE
;
2448 // pretend we have done something
2452 if (m_wxwindow
&& m_wxwindow
->window
)
2454 /* wxMSW doesn't clear the window here. I don't do that either to
2455 provide compatibility. call Clear() to do the job. */
2457 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2458 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2461 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2463 if (sysbg
== m_backgroundColour
)
2465 m_backgroundColour
= wxNullColour
;
2467 m_backgroundColour
= sysbg
;
2477 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2479 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2481 if (!wxWindowBase::SetForegroundColour(colour
))
2483 // don't leave if the GTK widget has just
2485 if (!m_delayedForegroundColour
) return FALSE
;
2488 GtkWidget
*connect_widget
= GetConnectWidget();
2489 if (!connect_widget
->window
)
2491 // indicate that a new style has been set
2492 // but it couldn't get applied as the
2493 // widget hasn't been realized yet.
2494 m_delayedForegroundColour
= TRUE
;
2496 // pretend we have done something
2500 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2501 if (sysbg
== m_foregroundColour
)
2503 m_backgroundColour
= wxNullColour
;
2505 m_backgroundColour
= sysbg
;
2515 GtkStyle
*wxWindow::GetWidgetStyle()
2517 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2519 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2521 return m_widgetStyle
;
2524 void wxWindow::SetWidgetStyle()
2526 GtkStyle
*style
= GetWidgetStyle();
2528 gdk_font_unref( style
->font
);
2529 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2531 if (m_foregroundColour
.Ok())
2533 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2534 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2535 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2536 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2539 if (m_backgroundColour
.Ok())
2541 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2542 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2543 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2544 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2545 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2546 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2547 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2548 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2549 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2553 void wxWindow::ApplyWidgetStyle()
2557 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2559 menu
->SetInvokingWindow( win
);
2560 wxNode
*node
= menu
->GetItems().First();
2563 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2564 if (menuitem
->IsSubMenu())
2566 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2568 node
= node
->Next();
2572 static gint gs_pop_x
= 0;
2573 static gint gs_pop_y
= 0;
2575 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2579 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2584 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2586 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2588 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2590 SetInvokingWindow( menu
, this );
2598 GTK_MENU(menu
->m_menu
),
2599 (GtkWidget
*) NULL
, // parent menu shell
2600 (GtkWidget
*) NULL
, // parent menu item
2601 (GtkMenuPositionFunc
) pop_pos_callback
,
2602 (gpointer
) this, // client data
2603 0, // button used to activate it
2604 0 //gs_timeLastClick // the time of activation
2609 #if wxUSE_DRAG_AND_DROP
2611 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2613 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2615 GtkWidget
*dnd_widget
= GetConnectWidget();
2617 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2619 if (m_dropTarget
) delete m_dropTarget
;
2620 m_dropTarget
= dropTarget
;
2622 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2625 #endif // wxUSE_DRAG_AND_DROP
2627 GtkWidget
* wxWindow::GetConnectWidget()
2629 GtkWidget
*connect_widget
= m_widget
;
2630 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2632 return connect_widget
;
2635 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2637 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2638 return (window
== m_widget
->window
);
2641 bool wxWindow::SetFont( const wxFont
&font
)
2643 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T( "invalid window") );
2645 if (!wxWindowBase::SetFont(font
))
2647 // don't leave if the GTK widget has just
2649 if (!m_delayedFont
) return FALSE
;
2652 GtkWidget
*connect_widget
= GetConnectWidget();
2653 if (!connect_widget
->window
)
2655 // indicate that a new style has been set
2656 // but it couldn't get applied as the
2657 // widget hasn't been realized yet.
2658 m_delayedFont
= TRUE
;
2660 // pretend we have done something
2664 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2665 if ( sysbg
== m_backgroundColour
)
2667 m_backgroundColour
= wxNullColour
;
2669 m_backgroundColour
= sysbg
;
2679 void wxWindow::CaptureMouse()
2681 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2683 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
2685 GtkWidget
*connect_widget
= GetConnectWidget();
2686 if (!connect_widget
->window
) return;
2688 gtk_grab_add( connect_widget
);
2689 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2691 (GDK_BUTTON_PRESS_MASK
|
2692 GDK_BUTTON_RELEASE_MASK
|
2693 GDK_POINTER_MOTION_MASK
),
2700 void wxWindow::ReleaseMouse()
2702 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2704 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
2706 GtkWidget
*connect_widget
= GetConnectWidget();
2707 if (!connect_widget
->window
) return;
2709 gtk_grab_remove( connect_widget
);
2710 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2711 g_capturing
= FALSE
;
2714 bool wxWindow::IsRetained() const
2719 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2720 int range
, bool refresh
)
2722 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2724 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2726 m_hasScrolling
= TRUE
;
2728 if (orient
== wxHORIZONTAL
)
2730 float fpos
= (float)pos
;
2731 float frange
= (float)range
;
2732 float fthumb
= (float)thumbVisible
;
2733 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2734 if (fpos
< 0.0) fpos
= 0.0;
2736 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2737 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2739 SetScrollPos( orient
, pos
, refresh
);
2743 m_oldHorizontalPos
= fpos
;
2745 m_hAdjust
->lower
= 0.0;
2746 m_hAdjust
->upper
= frange
;
2747 m_hAdjust
->value
= fpos
;
2748 m_hAdjust
->step_increment
= 1.0;
2749 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2750 m_hAdjust
->page_size
= fthumb
;
2754 float fpos
= (float)pos
;
2755 float frange
= (float)range
;
2756 float fthumb
= (float)thumbVisible
;
2757 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2758 if (fpos
< 0.0) fpos
= 0.0;
2760 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2761 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2763 SetScrollPos( orient
, pos
, refresh
);
2767 m_oldVerticalPos
= fpos
;
2769 m_vAdjust
->lower
= 0.0;
2770 m_vAdjust
->upper
= frange
;
2771 m_vAdjust
->value
= fpos
;
2772 m_vAdjust
->step_increment
= 1.0;
2773 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2774 m_vAdjust
->page_size
= fthumb
;
2777 if (orient
== wxHORIZONTAL
)
2778 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2780 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2783 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2785 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2787 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2789 if (orient
== wxHORIZONTAL
)
2791 float fpos
= (float)pos
;
2792 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2793 if (fpos
< 0.0) fpos
= 0.0;
2794 m_oldHorizontalPos
= fpos
;
2796 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2797 m_hAdjust
->value
= fpos
;
2801 float fpos
= (float)pos
;
2802 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2803 if (fpos
< 0.0) fpos
= 0.0;
2804 m_oldVerticalPos
= fpos
;
2806 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2807 m_vAdjust
->value
= fpos
;
2810 if (!m_isScrolling
) /* prevent recursion */
2812 if (m_wxwindow
->window
)
2814 if (orient
== wxHORIZONTAL
)
2815 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2817 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2822 int wxWindow::GetScrollThumb( int orient
) const
2824 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2826 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2828 if (orient
== wxHORIZONTAL
)
2829 return (int)(m_hAdjust
->page_size
+0.5);
2831 return (int)(m_vAdjust
->page_size
+0.5);
2834 int wxWindow::GetScrollPos( int orient
) const
2836 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2838 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2840 if (orient
== wxHORIZONTAL
)
2841 return (int)(m_hAdjust
->value
+0.5);
2843 return (int)(m_vAdjust
->value
+0.5);
2846 int wxWindow::GetScrollRange( int orient
) const
2848 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2850 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2852 if (orient
== wxHORIZONTAL
)
2853 return (int)(m_hAdjust
->upper
+0.5);
2855 return (int)(m_vAdjust
->upper
+0.5);
2858 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2860 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2862 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2866 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2867 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2872 GetClientSize( &cw
, &ch
);
2873 int w
= cw
- abs(dx
);
2874 int h
= ch
- abs(dy
);
2876 if ((h
< 0) || (w
< 0))
2884 if (dx
< 0) s_x
= -dx
;
2885 if (dy
< 0) s_y
= -dy
;
2888 if (dx
> 0) d_x
= dx
;
2889 if (dy
> 0) d_y
= dy
;
2891 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2892 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2895 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2896 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2897 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2898 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2900 Refresh( TRUE
, &rect
);
2903 wxNode
*node
= m_children
.First();
2906 wxWindow
*child
= (wxWindow
*) node
->Data();
2907 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
2908 node
= node
->Next();
2912 void wxWindow::SetScrolling(bool scroll
)
2914 m_isScrolling
= g_blockEventsOnScroll
= scroll
;