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
)
299 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
301 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
302 case GDK_Menu
: key_code
= WXK_MENU
; break;
303 case GDK_Help
: key_code
= WXK_HELP
; break;
304 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
305 case GDK_ISO_Left_Tab
:
306 case GDK_Tab
: key_code
= WXK_TAB
; break;
307 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
308 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
309 case GDK_Return
: key_code
= WXK_RETURN
; break;
310 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
311 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
312 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
313 case GDK_Delete
: key_code
= WXK_DELETE
; break;
314 case GDK_Home
: key_code
= WXK_HOME
; break;
315 case GDK_Left
: key_code
= WXK_LEFT
; break;
316 case GDK_Up
: key_code
= WXK_UP
; break;
317 case GDK_Right
: key_code
= WXK_RIGHT
; break;
318 case GDK_Down
: key_code
= WXK_DOWN
; break;
319 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
320 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
321 case GDK_Next
: key_code
= WXK_NEXT
; break;
322 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
323 case GDK_End
: key_code
= WXK_END
; break;
324 case GDK_Begin
: key_code
= WXK_HOME
; break;
325 case GDK_Select
: key_code
= WXK_SELECT
; break;
326 case GDK_Print
: key_code
= WXK_PRINT
; break;
327 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
328 case GDK_Insert
: key_code
= WXK_INSERT
; break;
329 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
331 case GDK_KP_0
: key_code
= '0'; break;
332 case GDK_KP_1
: key_code
= '1'; break;
333 case GDK_KP_2
: key_code
= '2'; break;
334 case GDK_KP_3
: key_code
= '3'; break;
335 case GDK_KP_4
: key_code
= '4'; break;
336 case GDK_KP_5
: key_code
= '5'; break;
337 case GDK_KP_6
: key_code
= '6'; break;
338 case GDK_KP_7
: key_code
= '7'; break;
339 case GDK_KP_8
: key_code
= '8'; break;
340 case GDK_KP_9
: key_code
= '9'; break;
341 case GDK_KP_Space
: key_code
= ' '; break;
342 case GDK_KP_Tab
: key_code
= WXK_TAB
; break; /* or '\t' ??? */
343 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break; /* or '\r' ??? */
344 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
345 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
346 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
347 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
348 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
349 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
350 case GDK_KP_Up
: key_code
= WXK_UP
; break;
351 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
352 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
353 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
354 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
355 case GDK_KP_Next
: key_code
= WXK_PRIOR
; break;
356 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
357 case GDK_KP_End
: key_code
= WXK_END
; break;
358 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
359 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
360 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
361 case GDK_KP_Equal
: key_code
= '='; break;
362 case GDK_KP_Multiply
: key_code
= '*'; break;
363 case GDK_KP_Add
: key_code
= '+'; break;
364 case GDK_KP_Separator
: key_code
= ','; break;
365 case GDK_KP_Subtract
: key_code
= '-'; break;
366 case GDK_KP_Decimal
: key_code
= '.'; break;
367 case GDK_KP_Divide
: key_code
= '/'; break;
369 case GDK_F1
: key_code
= WXK_F1
; break;
370 case GDK_F2
: key_code
= WXK_F2
; break;
371 case GDK_F3
: key_code
= WXK_F3
; break;
372 case GDK_F4
: key_code
= WXK_F4
; break;
373 case GDK_F5
: key_code
= WXK_F5
; break;
374 case GDK_F6
: key_code
= WXK_F6
; break;
375 case GDK_F7
: key_code
= WXK_F7
; break;
376 case GDK_F8
: key_code
= WXK_F8
; break;
377 case GDK_F9
: key_code
= WXK_F9
; break;
378 case GDK_F10
: key_code
= WXK_F10
; break;
379 case GDK_F11
: key_code
= WXK_F11
; break;
380 case GDK_F12
: key_code
= WXK_F12
; break;
393 static long get_unmodified_wx_keysym( GdkEventKey
*event
)
395 KeyCode keycode
= XKeysymToKeycode( GDK_DISPLAY(), event
->keyval
);
396 KeySym keysym
= XKeycodeToKeysym( GDK_DISPLAY(), keycode
, 0 );
398 return (map_to_unmodified_wx_keysym( keysym
));
401 //-----------------------------------------------------------------------------
402 // local code (see below)
403 //-----------------------------------------------------------------------------
405 #if (GTK_MINOR_VERSION > 0)
407 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
415 if (win
->HasScrolling())
417 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
418 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
421 GtkWidget *hscrollbar = scroll_window->hscrollbar;
422 GtkWidget *vscrollbar = scroll_window->vscrollbar;
424 we use this instead: range.slider_width = 11 + 2*2pts edge
427 if (scroll_window
->vscrollbar_visible
)
429 dw
+= 15; /* dw += vscrollbar->allocation.width; */
430 dw
+= scroll_class
->scrollbar_spacing
;
433 if (scroll_window
->hscrollbar_visible
)
435 dh
+= 15; /* dh += hscrollbar->allocation.height; */
436 dw
+= scroll_class
->scrollbar_spacing
;
442 if (GTK_WIDGET_NO_WINDOW (widget
))
444 dx
+= widget
->allocation
.x
;
445 dy
+= widget
->allocation
.y
;
448 if (win
->HasFlag(wxRAISED_BORDER
))
450 gtk_draw_shadow( widget
->style
,
455 win
->m_width
-dw
, win
->m_height
-dh
);
459 if (win
->HasFlag(wxSUNKEN_BORDER
))
461 gtk_draw_shadow( widget
->style
,
466 win
->m_width
-dw
, win
->m_height
-dh
);
471 //-----------------------------------------------------------------------------
472 // "expose_event" of m_widget
473 //-----------------------------------------------------------------------------
475 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
477 if (gdk_event
->count
> 0) return;
478 draw_frame( widget
, win
);
481 //-----------------------------------------------------------------------------
482 // "draw" of m_wxwindow
483 //-----------------------------------------------------------------------------
485 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
487 draw_frame( widget
, win
);
490 #endif // GTK_MINOR_VERSION > 0
492 //-----------------------------------------------------------------------------
493 // "expose_event" of m_wxwindow
494 //-----------------------------------------------------------------------------
496 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
498 if ( !win
->m_hasVMT
)
501 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
503 gdk_event
->area
.width
,
504 gdk_event
->area
.height
);
506 if ( gdk_event
->count
> 0 )
510 printf( "OnExpose from " );
511 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
512 printf( win->GetClassInfo()->GetClassName() );
516 wxPaintEvent
event( win
->GetId() );
517 event
.SetEventObject( win
);
518 win
->GetEventHandler()->ProcessEvent( event
);
520 win
->GetUpdateRegion().Clear();
523 //-----------------------------------------------------------------------------
524 // "draw" of m_wxwindow
525 //-----------------------------------------------------------------------------
527 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
530 wxapp_install_idle_handler();
535 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
536 rect
->width
, rect
->height
);
538 wxPaintEvent
event( win
->GetId() );
539 event
.SetEventObject( win
);
540 win
->GetEventHandler()->ProcessEvent( event
);
542 win
->GetUpdateRegion().Clear();
545 //-----------------------------------------------------------------------------
546 // "key_press_event" from any window
547 //-----------------------------------------------------------------------------
549 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
552 wxapp_install_idle_handler();
554 if (!win
->m_hasVMT
) return FALSE
;
555 if (g_blockEventsOnDrag
) return FALSE
;
558 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
559 if (gdk_event->state & GDK_SHIFT_MASK)
560 printf( "ShiftDown.\n" );
562 printf( "ShiftUp.\n" );
563 if (gdk_event->state & GDK_CONTROL_MASK)
564 printf( "ControlDown.\n" );
566 printf( "ControlUp.\n" );
574 GdkModifierType state
;
575 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
577 long key_code
= get_unmodified_wx_keysym( gdk_event
);
579 wxKeyEvent
event( wxEVT_KEY_DOWN
);
580 event
.SetTimestamp( gdk_event
->time
);
581 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
582 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
583 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
584 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
585 event
.m_keyCode
= key_code
;
586 event
.m_scanCode
= gdk_event
->keyval
;
589 event
.SetEventObject( win
);
590 ret
= win
->GetEventHandler()->ProcessEvent( event
);
592 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
594 /* wxMSW doesn't send char events with Alt pressed */
595 if (((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
);
711 GdkModifierType state
;
712 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
714 wxKeyEvent
event( wxEVT_KEY_UP
);
715 event
.SetTimestamp( gdk_event
->time
);
716 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
717 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
718 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
719 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
720 event
.m_keyCode
= key_code
;
721 event
.m_scanCode
= gdk_event
->keyval
;
724 event
.SetEventObject( win
);
726 if (win
->GetEventHandler()->ProcessEvent( event
))
728 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
735 //-----------------------------------------------------------------------------
736 // "button_press_event"
737 //-----------------------------------------------------------------------------
739 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
742 wxapp_install_idle_handler();
745 wxPrintf( _T("1) OnButtonPress from ") );
746 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
747 wxPrintf( win->GetClassInfo()->GetClassName() );
748 wxPrintf( _T(".\n") );
750 if (!win
->m_hasVMT
) return FALSE
;
751 if (g_blockEventsOnDrag
) return TRUE
;
752 if (g_blockEventsOnScroll
) return TRUE
;
754 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
758 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
760 gtk_widget_grab_focus (win
->m_wxwindow
);
763 wxPrintf( _T("GrabFocus from ") );
764 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
765 wxPrintf( win->GetClassInfo()->GetClassName() );
766 wxPrintf( _T(".\n") );
773 wxPrintf( _T("2) OnButtonPress from ") );
774 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
775 wxPrintf( win->GetClassInfo()->GetClassName() );
776 wxPrintf( _T(".\n") );
779 wxEventType event_type
= wxEVT_LEFT_DOWN
;
781 if (gdk_event
->button
== 1)
783 switch (gdk_event
->type
)
785 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
786 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
790 else if (gdk_event
->button
== 2)
792 switch (gdk_event
->type
)
794 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
795 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
799 else if (gdk_event
->button
== 3)
801 switch (gdk_event
->type
)
803 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
804 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
809 wxMouseEvent
event( event_type
);
810 event
.SetTimestamp( gdk_event
->time
);
811 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
812 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
813 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
814 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
815 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
816 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
817 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
819 event
.m_x
= (long)gdk_event
->x
;
820 event
.m_y
= (long)gdk_event
->y
;
822 // Some control don't have their own X window and thus cannot get
827 wxNode
*node
= win
->GetChildren().First();
830 wxWindow
*child
= (wxWindow
*)node
->Data();
832 if (child
->m_isStaticBox
)
834 // wxStaticBox is transparent in the box itself
837 int xx1
= child
->m_x
;
838 int yy1
= child
->m_y
;
839 int xx2
= child
->m_x
+ child
->m_width
;
840 int yy2
= child
->m_x
+ child
->m_height
;
843 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
845 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
847 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
849 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
852 event
.m_x
-= child
->m_x
;
853 event
.m_y
-= child
->m_y
;
860 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
861 (child
->m_x
<= event
.m_x
) &&
862 (child
->m_y
<= event
.m_y
) &&
863 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
864 (child
->m_y
+child
->m_height
>= event
.m_y
))
867 event
.m_x
-= child
->m_x
;
868 event
.m_y
-= child
->m_y
;
876 event
.SetEventObject( win
);
878 gs_timeLastClick
= gdk_event
->time
;
880 if (win
->GetEventHandler()->ProcessEvent( event
))
882 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
889 //-----------------------------------------------------------------------------
890 // "button_release_event"
891 //-----------------------------------------------------------------------------
893 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
896 wxapp_install_idle_handler();
898 if (!win
->m_hasVMT
) return FALSE
;
899 if (g_blockEventsOnDrag
) return FALSE
;
900 if (g_blockEventsOnScroll
) return FALSE
;
902 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
905 printf( "OnButtonRelease from " );
906 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
907 printf( win->GetClassInfo()->GetClassName() );
911 wxEventType event_type
= wxEVT_NULL
;
913 switch (gdk_event
->button
)
915 case 1: event_type
= wxEVT_LEFT_UP
; break;
916 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
917 case 3: event_type
= wxEVT_RIGHT_UP
; break;
920 wxMouseEvent
event( event_type
);
921 event
.SetTimestamp( gdk_event
->time
);
922 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
923 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
924 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
925 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
926 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
927 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
928 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
929 event
.m_x
= (long)gdk_event
->x
;
930 event
.m_y
= (long)gdk_event
->y
;
932 // Some control don't have their own X window and thus cannot get
937 wxNode
*node
= win
->GetChildren().First();
940 wxWindow
*child
= (wxWindow
*)node
->Data();
942 if (child
->m_isStaticBox
)
944 // wxStaticBox is transparent in the box itself
947 int xx1
= child
->m_x
;
948 int yy1
= child
->m_y
;
949 int xx2
= child
->m_x
+ child
->m_width
;
950 int yy2
= child
->m_x
+ child
->m_height
;
953 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
955 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
957 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
959 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
962 event
.m_x
-= child
->m_x
;
963 event
.m_y
-= child
->m_y
;
970 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
971 (child
->m_x
<= event
.m_x
) &&
972 (child
->m_y
<= event
.m_y
) &&
973 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
974 (child
->m_y
+child
->m_height
>= event
.m_y
))
977 event
.m_x
-= child
->m_x
;
978 event
.m_y
-= child
->m_y
;
986 event
.SetEventObject( win
);
988 if (win
->GetEventHandler()->ProcessEvent( event
))
990 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
997 //-----------------------------------------------------------------------------
998 // "motion_notify_event"
999 //-----------------------------------------------------------------------------
1001 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1004 wxapp_install_idle_handler();
1006 if (!win
->m_hasVMT
) return FALSE
;
1007 if (g_blockEventsOnDrag
) return FALSE
;
1008 if (g_blockEventsOnScroll
) return FALSE
;
1010 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1012 if (gdk_event
->is_hint
)
1016 GdkModifierType state
;
1017 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1020 gdk_event
->state
= state
;
1024 printf( "OnMotion from " );
1025 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1026 printf( win->GetClassInfo()->GetClassName() );
1030 wxMouseEvent
event( wxEVT_MOTION
);
1031 event
.SetTimestamp( gdk_event
->time
);
1032 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1033 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1034 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1035 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1036 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1037 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1038 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1040 event
.m_x
= (long)gdk_event
->x
;
1041 event
.m_y
= (long)gdk_event
->y
;
1043 // Some control don't have their own X window and thus cannot get
1048 wxNode
*node
= win
->GetChildren().First();
1051 wxWindow
*child
= (wxWindow
*)node
->Data();
1053 if (child
->m_isStaticBox
)
1055 // wxStaticBox is transparent in the box itself
1058 int xx1
= child
->m_x
;
1059 int yy1
= child
->m_y
;
1060 int xx2
= child
->m_x
+ child
->m_width
;
1061 int yy2
= child
->m_x
+ child
->m_height
;
1064 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1066 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1068 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1070 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1073 event
.m_x
-= child
->m_x
;
1074 event
.m_y
-= child
->m_y
;
1081 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1082 (child
->m_x
<= event
.m_x
) &&
1083 (child
->m_y
<= event
.m_y
) &&
1084 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1085 (child
->m_y
+child
->m_height
>= event
.m_y
))
1088 event
.m_x
-= child
->m_x
;
1089 event
.m_y
-= child
->m_y
;
1093 node
= node
->Next();
1097 event
.SetEventObject( win
);
1099 if (win
->GetEventHandler()->ProcessEvent( event
))
1101 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1108 //-----------------------------------------------------------------------------
1110 //-----------------------------------------------------------------------------
1112 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1115 wxapp_install_idle_handler();
1117 if (!win
->m_hasVMT
) return FALSE
;
1118 if (g_blockEventsOnDrag
) return FALSE
;
1120 g_focusWindow
= win
;
1122 if (win
->m_wxwindow
)
1124 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1126 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1128 printf( "SetFocus flag from " );
1129 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1130 printf( win->GetClassInfo()->GetClassName() );
1138 printf( "OnSetFocus from " );
1139 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1140 printf( win->GetClassInfo()->GetClassName() );
1142 printf( WXSTRINGCAST win->GetLabel() );
1146 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1147 event
.SetEventObject( win
);
1149 if (win
->GetEventHandler()->ProcessEvent( event
))
1151 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1158 //-----------------------------------------------------------------------------
1159 // "focus_out_event"
1160 //-----------------------------------------------------------------------------
1162 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1165 wxapp_install_idle_handler();
1167 if (!win
->m_hasVMT
) return FALSE
;
1168 if (g_blockEventsOnDrag
) return FALSE
;
1170 if (win
->m_wxwindow
)
1172 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1173 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1177 printf( "OnKillFocus from " );
1178 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1179 printf( win->GetClassInfo()->GetClassName() );
1183 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1184 event
.SetEventObject( win
);
1186 if (win
->GetEventHandler()->ProcessEvent( event
))
1188 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1195 //-----------------------------------------------------------------------------
1196 // "enter_notify_event"
1197 //-----------------------------------------------------------------------------
1199 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1202 wxapp_install_idle_handler();
1204 if (!win
->m_hasVMT
) return FALSE
;
1205 if (g_blockEventsOnDrag
) return FALSE
;
1207 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1209 if (widget
->window
&& win
->GetCursor().Ok() )
1210 gdk_window_set_cursor( widget
->window
, win
->GetCursor().GetCursor() );
1212 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1213 event
.SetTimestamp( gdk_event
->time
);
1214 event
.SetEventObject( win
);
1218 GdkModifierType state
= (GdkModifierType
)0;
1220 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1222 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1223 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1224 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1225 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1226 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1227 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1228 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1230 event
.m_x
= (long)x
;
1231 event
.m_y
= (long)y
;
1233 if (win
->GetEventHandler()->ProcessEvent( event
))
1235 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1242 //-----------------------------------------------------------------------------
1243 // "leave_notify_event"
1244 //-----------------------------------------------------------------------------
1246 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1249 wxapp_install_idle_handler();
1251 if (!win
->m_hasVMT
) return FALSE
;
1252 if (g_blockEventsOnDrag
) return FALSE
;
1254 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1256 if (widget
->window
&& win
->GetCursor().Ok() )
1257 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1259 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1260 event
.SetTimestamp( gdk_event
->time
);
1261 event
.SetEventObject( win
);
1265 GdkModifierType state
= (GdkModifierType
)0;
1267 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1269 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1270 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1271 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1272 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1273 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1274 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1275 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1277 event
.m_x
= (long)x
;
1278 event
.m_y
= (long)y
;
1280 if (win
->GetEventHandler()->ProcessEvent( event
))
1282 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1289 //-----------------------------------------------------------------------------
1290 // "value_changed" from m_vAdjust
1291 //-----------------------------------------------------------------------------
1293 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1296 wxapp_install_idle_handler();
1298 if (g_blockEventsOnDrag
) return;
1300 if (!win
->m_hasVMT
) return;
1302 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1303 if (fabs(diff
) < 0.2) return;
1304 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1306 wxEventType command
= wxEVT_NULL
;
1308 float line_step
= win
->m_vAdjust
->step_increment
;
1309 float page_step
= win
->m_vAdjust
->page_increment
;
1311 if (win
->IsScrolling())
1313 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1317 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1318 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1319 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1320 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1321 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1322 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1323 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1326 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1328 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1329 event
.SetEventObject( win
);
1330 win
->GetEventHandler()->ProcessEvent( event
);
1333 //-----------------------------------------------------------------------------
1334 // "value_changed" from m_hAdjust
1335 //-----------------------------------------------------------------------------
1337 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1340 wxapp_install_idle_handler();
1342 if (g_blockEventsOnDrag
) return;
1343 if (!win
->m_hasVMT
) return;
1345 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1346 if (fabs(diff
) < 0.2) return;
1347 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1349 wxEventType command
= wxEVT_NULL
;
1351 float line_step
= win
->m_hAdjust
->step_increment
;
1352 float page_step
= win
->m_hAdjust
->page_increment
;
1354 if (win
->IsScrolling())
1356 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1360 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1361 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1362 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1363 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1364 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1365 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1366 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1369 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1371 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1372 event
.SetEventObject( win
);
1373 win
->GetEventHandler()->ProcessEvent( event
);
1376 //-----------------------------------------------------------------------------
1377 // "changed" from m_vAdjust
1378 //-----------------------------------------------------------------------------
1380 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1383 wxapp_install_idle_handler();
1385 if (g_blockEventsOnDrag
) return;
1386 if (!win
->m_hasVMT
) return;
1388 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1389 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1391 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1392 event
.SetEventObject( win
);
1393 win
->GetEventHandler()->ProcessEvent( event
);
1396 //-----------------------------------------------------------------------------
1397 // "changed" from m_hAdjust
1398 //-----------------------------------------------------------------------------
1400 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1403 wxapp_install_idle_handler();
1405 if (g_blockEventsOnDrag
) return;
1406 if (!win
->m_hasVMT
) return;
1408 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1409 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1411 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1412 event
.SetEventObject( win
);
1413 win
->GetEventHandler()->ProcessEvent( event
);
1416 //-----------------------------------------------------------------------------
1417 // "button_press_event" from scrollbar
1418 //-----------------------------------------------------------------------------
1420 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1421 GdkEventButton
*WXUNUSED(gdk_event
),
1425 wxapp_install_idle_handler();
1427 // don't test here as we can release the mouse while being over
1428 // a different window then the slider
1430 // if (gdk_event->window != widget->slider) return FALSE;
1432 win
->SetScrolling( TRUE
);
1437 //-----------------------------------------------------------------------------
1438 // "button_release_event" from scrollbar
1439 //-----------------------------------------------------------------------------
1441 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1442 GdkEventButton
*WXUNUSED(gdk_event
),
1446 // don't test here as we can release the mouse while being over
1447 // a different window then the slider
1449 // if (gdk_event->window != widget->slider) return FALSE;
1451 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1453 if (widget
== GTK_RANGE(scrolledWindow
->vscrollbar
))
1454 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1456 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1458 win
->SetScrolling( FALSE
);
1463 // ----------------------------------------------------------------------------
1464 // this wxWindowBase function is implemented here (in platform-specific file)
1465 // because it is static and so couldn't be made virtual
1466 // ----------------------------------------------------------------------------
1468 wxWindow
*wxWindowBase::FindFocus()
1470 return g_focusWindow
;
1473 //-----------------------------------------------------------------------------
1474 // "realize" from m_widget
1475 //-----------------------------------------------------------------------------
1477 /* we cannot set colours, fonts and cursors before the widget has
1478 been realized, so we do this directly after realization */
1481 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1484 wxapp_install_idle_handler();
1486 if (win
->m_delayedFont
)
1487 win
->SetFont( win
->GetFont() );
1489 if (win
->m_delayedBackgroundColour
)
1490 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1492 if (win
->m_delayedForegroundColour
)
1493 win
->SetForegroundColour( win
->GetForegroundColour() );
1495 win
->SetCursor( win
->GetCursor() );
1500 //-----------------------------------------------------------------------------
1501 // InsertChild for wxWindow.
1502 //-----------------------------------------------------------------------------
1504 /* Callback for wxWindow. This very strange beast has to be used because
1505 * C++ has no virtual methods in a constructor. We have to emulate a
1506 * virtual function here as wxNotebook requires a different way to insert
1507 * a child in it. I had opted for creating a wxNotebookPage window class
1508 * which would have made this superfluous (such in the MDI window system),
1509 * but no-one was listening to me... */
1511 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1513 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1514 GTK_WIDGET(child
->m_widget
),
1520 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1522 /* we now allow a window to get the focus as long as it
1523 doesn't have any children. */
1524 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1528 //-----------------------------------------------------------------------------
1530 //-----------------------------------------------------------------------------
1532 wxWindow
* wxGetActiveWindow()
1534 return g_focusWindow
;
1537 //-----------------------------------------------------------------------------
1539 //-----------------------------------------------------------------------------
1541 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1543 void wxWindow::Init()
1549 m_widget
= (GtkWidget
*) NULL
;
1550 m_wxwindow
= (GtkWidget
*) NULL
;
1560 m_needParent
= TRUE
;
1561 m_isBeingDeleted
= FALSE
;
1563 m_hasScrolling
= FALSE
;
1564 m_isScrolling
= FALSE
;
1566 m_hAdjust
= (GtkAdjustment
*) NULL
;
1567 m_vAdjust
= (GtkAdjustment
*) NULL
;
1568 m_oldHorizontalPos
= 0.0;
1569 m_oldVerticalPos
= 0.0;
1572 m_scrollGC
= (GdkGC
*) NULL
;
1573 m_widgetStyle
= (GtkStyle
*) NULL
;
1575 m_insertCallback
= wxInsertChildInWindow
;
1577 m_isStaticBox
= FALSE
;
1578 m_acceptsFocus
= FALSE
;
1581 wxWindow::wxWindow()
1586 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1587 const wxPoint
&pos
, const wxSize
&size
,
1588 long style
, const wxString
&name
)
1592 Create( parent
, id
, pos
, size
, style
, name
);
1595 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1596 const wxPoint
&pos
, const wxSize
&size
,
1597 long style
, const wxString
&name
)
1599 PreCreation( parent
, id
, pos
, size
, style
, name
);
1601 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1602 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1605 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1608 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1611 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1612 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1615 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1616 scroll_class
->scrollbar_spacing
= 0;
1618 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1620 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1621 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1623 m_wxwindow
= gtk_myfixed_new();
1626 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1629 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1631 #if (GTK_MINOR_VERSION > 0)
1632 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1634 if (HasFlag(wxRAISED_BORDER
))
1636 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1638 else if (HasFlag(wxSUNKEN_BORDER
))
1640 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1644 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1646 #else // GTK_MINOR_VERSION == 0
1647 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1649 if (HasFlag(wxRAISED_BORDER
))
1651 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1653 else if (HasFlag(wxSUNKEN_BORDER
))
1655 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1659 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1661 #endif // GTK_MINOR_VERSION
1663 if (HasFlag(wxTAB_TRAVERSAL
))
1665 /* we now allow a window to get the focus as long as it
1666 doesn't have any children. */
1667 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1668 m_acceptsFocus
= FALSE
;
1672 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1673 m_acceptsFocus
= TRUE
;
1676 #if (GTK_MINOR_VERSION == 0)
1677 // shut the viewport up
1678 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1679 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1680 #endif // GTK_MINOR_VERSION == 0
1682 // I _really_ don't want scrollbars in the beginning
1683 m_vAdjust
->lower
= 0.0;
1684 m_vAdjust
->upper
= 1.0;
1685 m_vAdjust
->value
= 0.0;
1686 m_vAdjust
->step_increment
= 1.0;
1687 m_vAdjust
->page_increment
= 1.0;
1688 m_vAdjust
->page_size
= 5.0;
1689 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1690 m_hAdjust
->lower
= 0.0;
1691 m_hAdjust
->upper
= 1.0;
1692 m_hAdjust
->value
= 0.0;
1693 m_hAdjust
->step_increment
= 1.0;
1694 m_hAdjust
->page_increment
= 1.0;
1695 m_hAdjust
->page_size
= 5.0;
1696 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1698 // these handlers block mouse events to any window during scrolling such as
1699 // motion events and prevent GTK and wxWindows from fighting over where the
1702 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1703 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1705 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1706 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1708 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1709 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1711 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1712 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1714 // these handlers get notified when screen updates are required either when
1715 // scrolling or when the window size (and therefore scrollbar configuration)
1718 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1719 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1720 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1721 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1723 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1724 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1725 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1726 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1728 gtk_widget_show( m_wxwindow
);
1731 m_parent
->DoAddChild( this );
1740 wxWindow::~wxWindow()
1742 m_isBeingDeleted
= TRUE
;
1751 m_parent
->RemoveChild( this );
1755 gtk_style_unref( m_widgetStyle
);
1756 m_widgetStyle
= (GtkStyle
*) NULL
;
1761 gdk_gc_unref( m_scrollGC
);
1762 m_scrollGC
= (GdkGC
*) NULL
;
1767 gtk_widget_destroy( m_wxwindow
);
1768 m_wxwindow
= (GtkWidget
*) NULL
;
1773 gtk_widget_destroy( m_widget
);
1774 m_widget
= (GtkWidget
*) NULL
;
1778 void wxWindow::PreCreation( wxWindow
*parent
,
1783 const wxString
&name
)
1785 wxASSERT_MSG( !m_needParent
|| parent
, _T("Need complete parent.") );
1787 if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) )
1789 wxFAIL_MSG(_T("window creation failed"));
1792 m_width
= WidthDefault(size
.x
);
1793 m_height
= HeightDefault(size
.y
);
1798 if (!parent
) /* some reasonable defaults */
1802 m_x
= (gdk_screen_width () - m_width
) / 2;
1803 if (m_x
< 10) m_x
= 10;
1807 m_y
= (gdk_screen_height () - m_height
) / 2;
1808 if (m_y
< 10) m_y
= 10;
1813 void wxWindow::PostCreation()
1815 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1819 /* these get reported to wxWindows -> wxPaintEvent */
1820 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1821 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1823 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1824 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1826 #if (GTK_MINOR_VERSION > 0)
1827 /* these are called when the "sunken" or "raised" borders are drawn */
1828 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1829 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1831 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1832 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1836 GtkWidget
*connect_widget
= GetConnectWidget();
1838 ConnectWidget( connect_widget
);
1840 /* we cannot set colours, fonts and cursors before the widget has
1841 been realized, so we do this directly after realization */
1842 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1843 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1848 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1850 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1851 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1853 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1854 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1856 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1857 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1859 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1860 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1862 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1863 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1865 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1866 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1868 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1869 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1871 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1872 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1874 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1875 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1878 bool wxWindow::Destroy()
1880 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1884 return wxWindowBase::Destroy();
1887 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1889 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1890 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1892 if (m_resizing
) return; /* I don't like recursions */
1895 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1897 /* don't set the size for children of wxNotebook, just take the values. */
1905 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1907 if (x
!= -1) m_x
= x
;
1908 if (y
!= -1) m_y
= y
;
1909 if (width
!= -1) m_width
= width
;
1910 if (height
!= -1) m_height
= height
;
1920 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1922 if (width
== -1) m_width
= 80;
1925 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1927 if (height
== -1) m_height
= 26;
1930 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1931 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1932 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1933 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1937 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1939 /* the default button has a border around it */
1943 /* this is the result of hours of debugging: the following code
1944 means that if we have a m_wxwindow and we set the size of
1945 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
1946 automatically propagate its size down to its m_wxwindow,
1947 which is its client area. therefore, we have to tell the
1948 client area directly that it has to resize itself.
1949 this will lead to that m_widget (GtkScrolledWindow) will
1950 calculate how much size it needs for scrollbars etc and
1951 it will then call XXX_size_allocate of its child, which
1952 is m_wxwindow. m_wxwindow in turn will do the same with its
1953 children and so on. problems can arise if this happens
1954 before all the children have been realized as some widgets
1955 stupidy need to be realized during XXX_size_allocate (e.g.
1956 GtkNotebook) and they will segv if called otherwise. this
1957 emergency is tested in gtk_myfixed_size_allocate. Normally
1958 this shouldn't be needed and only gtk_widget_queue_resize()
1959 should be enough to provoke a resize at the next appropriate
1960 moment, but this seems to fail, e.g. when a wxNotebook contains
1961 a wxSplitterWindow: the splitter window's children won't
1962 show up properly resized then. */
1964 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
1969 m_height
+2*border
);
1974 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1975 event
.SetEventObject( this );
1976 GetEventHandler()->ProcessEvent( event
);
1981 void wxWindow::OnInternalIdle()
1986 void wxWindow::DoGetSize( int *width
, int *height
) const
1988 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
1990 if (width
) (*width
) = m_width
;
1991 if (height
) (*height
) = m_height
;
1994 void wxWindow::DoSetClientSize( int width
, int height
)
1996 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2000 SetSize( width
, height
);
2007 if (!m_hasScrolling
)
2009 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2011 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2013 dw
+= 2 * window_class
->xthickness
;
2014 dh
+= 2 * window_class
->ythickness
;
2019 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2020 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2022 #if (GTK_MINOR_VERSION == 0)
2023 GtkWidget
*viewport
= scroll_window
->viewport
;
2024 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2026 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2028 dw
+= 2 * viewport_class
->xthickness
;
2029 dh
+= 2 * viewport_class
->ythickness
;
2034 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2035 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2037 we use this instead: range.slider_width = 11 + 2*2pts edge
2040 if (scroll_window
->vscrollbar_visible
)
2042 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2043 dw
+= scroll_class
->scrollbar_spacing
;
2046 if (scroll_window
->hscrollbar_visible
)
2048 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2049 dw
+= scroll_class
->scrollbar_spacing
;
2053 SetSize( width
+dw
, height
+dh
);
2057 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2059 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2063 if (width
) (*width
) = m_width
;
2064 if (height
) (*height
) = m_height
;
2071 if (!m_hasScrolling
)
2073 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2075 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2077 dw
+= 2 * window_class
->xthickness
;
2078 dh
+= 2 * window_class
->ythickness
;
2083 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2084 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2086 #if (GTK_MINOR_VERSION == 0)
2087 GtkWidget
*viewport
= scroll_window
->viewport
;
2088 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2090 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) )
2092 dw
+= 2 * viewport_class
->xthickness
;
2093 dh
+= 2 * viewport_class
->ythickness
;
2097 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2098 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2100 we use this instead: range.slider_width = 11 + 2*2pts edge
2103 if (scroll_window
->vscrollbar_visible
)
2105 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2106 dw
+= scroll_class
->scrollbar_spacing
;
2109 if (scroll_window
->hscrollbar_visible
)
2111 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2112 dh
+= scroll_class
->scrollbar_spacing
;
2116 if (width
) (*width
) = m_width
- dw
;
2117 if (height
) (*height
) = m_height
- dh
;
2121 void wxWindow::DoGetPosition( int *x
, int *y
) const
2123 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2129 void wxWindow::ClientToScreen( int *x
, int *y
) const
2131 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2133 if (!m_widget
->window
) return;
2135 GdkWindow
*source
= (GdkWindow
*) NULL
;
2137 source
= m_wxwindow
->window
;
2139 source
= m_widget
->window
;
2143 gdk_window_get_origin( source
, &org_x
, &org_y
);
2147 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2149 org_x
+= m_widget
->allocation
.x
;
2150 org_y
+= m_widget
->allocation
.y
;
2158 void wxWindow::ScreenToClient( int *x
, int *y
) const
2160 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2162 if (!m_widget
->window
) return;
2164 GdkWindow
*source
= (GdkWindow
*) NULL
;
2166 source
= m_wxwindow
->window
;
2168 source
= m_widget
->window
;
2172 gdk_window_get_origin( source
, &org_x
, &org_y
);
2176 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2178 org_x
+= m_widget
->allocation
.x
;
2179 org_y
+= m_widget
->allocation
.y
;
2187 bool wxWindow::Show( bool show
)
2189 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2191 if (!wxWindowBase::Show(show
))
2198 gtk_widget_show( m_widget
);
2200 gtk_widget_hide( m_widget
);
2205 bool wxWindow::Enable( bool enable
)
2207 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2209 if (!wxWindowBase::Enable(enable
))
2215 gtk_widget_set_sensitive( m_widget
, enable
);
2217 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2222 int wxWindow::GetCharHeight() const
2224 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2226 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2228 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2230 return font
->ascent
+ font
->descent
;
2233 int wxWindow::GetCharWidth() const
2235 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2237 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2239 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2241 return gdk_string_width( font
, "H" );
2244 void wxWindow::GetTextExtent( const wxString
& string
,
2248 int *externalLeading
,
2249 const wxFont
*theFont
) const
2251 wxFont fontToUse
= m_font
;
2252 if (theFont
) fontToUse
= *theFont
;
2254 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2256 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2257 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2258 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2259 if (descent
) (*descent
) = font
->descent
;
2260 if (externalLeading
) (*externalLeading
) = 0; // ??
2263 void wxWindow::SetFocus()
2265 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2267 GtkWidget
*connect_widget
= GetConnectWidget();
2270 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2272 gtk_widget_grab_focus (connect_widget
);
2274 else if (GTK_IS_CONTAINER(connect_widget
))
2276 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2284 bool wxWindow::AcceptsFocus() const
2286 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2289 bool wxWindow::Reparent( wxWindow
*newParent
)
2291 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2293 gtk_widget_unparent( m_widget
);
2295 if ( !wxWindowBase::Reparent(newParent
) )
2301 void wxWindow::Raise()
2303 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2305 if (!m_widget
->window
) return;
2307 gdk_window_raise( m_widget
->window
);
2310 void wxWindow::Lower()
2312 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2314 if (!m_widget
->window
) return;
2316 gdk_window_lower( m_widget
->window
);
2319 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2321 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2323 if (!wxWindowBase::SetCursor(cursor
))
2325 // don't leave if the GTK widget has just
2327 if (!m_delayedCursor
) return FALSE
;
2330 GtkWidget
*connect_widget
= GetConnectWidget();
2331 if (!connect_widget
->window
)
2333 // indicate that a new style has been set
2334 // but it couldn't get applied as the
2335 // widget hasn't been realized yet.
2336 m_delayedCursor
= TRUE
;
2338 // pretend we have done something
2342 if ((m_widget
) && (m_widget
->window
))
2343 gdk_window_set_cursor( m_widget
->window
, GetCursor().GetCursor() );
2345 if ((m_wxwindow
) && (m_wxwindow
->window
))
2346 gdk_window_set_cursor( m_wxwindow
->window
, GetCursor().GetCursor() );
2352 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2357 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2359 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2361 if (!m_widget
->window
) return;
2363 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2367 gdk_window_clear_area( m_wxwindow
->window
,
2369 rect
->width
, rect
->height
);
2373 gdk_window_clear( m_wxwindow
->window
);
2380 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2382 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2386 GdkRectangle gdk_rect
;
2387 gdk_rect
.x
= rect
->x
;
2388 gdk_rect
.y
= rect
->y
;
2389 gdk_rect
.width
= rect
->width
;
2390 gdk_rect
.height
= rect
->height
;
2393 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2395 gtk_widget_draw( m_widget
, &gdk_rect
);
2399 void wxWindow::Clear()
2401 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2403 if (!m_widget
->window
) return;
2405 if (m_wxwindow
&& m_wxwindow
->window
)
2407 gdk_window_clear( m_wxwindow
->window
);
2412 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2414 wxWindowBase::DoSetToolTip(tip
);
2417 m_tooltip
->Apply( this );
2420 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2422 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2424 #endif // wxUSE_TOOLTIPS
2426 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2428 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2430 if (!wxWindowBase::SetBackgroundColour(colour
))
2432 // don't leave if the GTK widget has just
2434 if (!m_delayedBackgroundColour
) return FALSE
;
2437 GtkWidget
*connect_widget
= GetConnectWidget();
2438 if (!connect_widget
->window
)
2440 // indicate that a new style has been set
2441 // but it couldn't get applied as the
2442 // widget hasn't been realized yet.
2443 m_delayedBackgroundColour
= TRUE
;
2445 // pretend we have done something
2449 if (m_wxwindow
&& m_wxwindow
->window
)
2451 /* wxMSW doesn't clear the window here. I don't do that either to
2452 provide compatibility. call Clear() to do the job. */
2454 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2455 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2458 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2460 if (sysbg
== m_backgroundColour
)
2462 m_backgroundColour
= wxNullColour
;
2464 m_backgroundColour
= sysbg
;
2474 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2476 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2478 if (!wxWindowBase::SetForegroundColour(colour
))
2480 // don't leave if the GTK widget has just
2482 if (!m_delayedForegroundColour
) return FALSE
;
2485 GtkWidget
*connect_widget
= GetConnectWidget();
2486 if (!connect_widget
->window
)
2488 // indicate that a new style has been set
2489 // but it couldn't get applied as the
2490 // widget hasn't been realized yet.
2491 m_delayedForegroundColour
= TRUE
;
2493 // pretend we have done something
2497 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2498 if (sysbg
== m_foregroundColour
)
2500 m_backgroundColour
= wxNullColour
;
2502 m_backgroundColour
= sysbg
;
2512 GtkStyle
*wxWindow::GetWidgetStyle()
2514 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2516 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2518 return m_widgetStyle
;
2521 void wxWindow::SetWidgetStyle()
2523 GtkStyle
*style
= GetWidgetStyle();
2525 gdk_font_unref( style
->font
);
2526 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2528 if (m_foregroundColour
.Ok())
2530 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2531 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2532 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2533 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2536 if (m_backgroundColour
.Ok())
2538 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2539 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2540 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2541 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2542 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2543 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2544 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2545 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2546 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2550 void wxWindow::ApplyWidgetStyle()
2554 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2556 menu
->SetInvokingWindow( win
);
2557 wxNode
*node
= menu
->GetItems().First();
2560 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2561 if (menuitem
->IsSubMenu())
2563 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2565 node
= node
->Next();
2569 static gint gs_pop_x
= 0;
2570 static gint gs_pop_y
= 0;
2572 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2576 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2581 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2583 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2585 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2587 SetInvokingWindow( menu
, this );
2595 GTK_MENU(menu
->m_menu
),
2596 (GtkWidget
*) NULL
, // parent menu shell
2597 (GtkWidget
*) NULL
, // parent menu item
2598 (GtkMenuPositionFunc
) pop_pos_callback
,
2599 (gpointer
) this, // client data
2600 0, // button used to activate it
2601 0 //gs_timeLastClick // the time of activation
2606 #if wxUSE_DRAG_AND_DROP
2608 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2610 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2612 GtkWidget
*dnd_widget
= GetConnectWidget();
2614 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2616 if (m_dropTarget
) delete m_dropTarget
;
2617 m_dropTarget
= dropTarget
;
2619 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2622 #endif // wxUSE_DRAG_AND_DROP
2624 GtkWidget
* wxWindow::GetConnectWidget()
2626 GtkWidget
*connect_widget
= m_widget
;
2627 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2629 return connect_widget
;
2632 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2634 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2635 return (window
== m_widget
->window
);
2638 bool wxWindow::SetFont( const wxFont
&font
)
2640 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T( "invalid window") );
2642 if (!wxWindowBase::SetFont(font
))
2644 // don't leave if the GTK widget has just
2646 if (!m_delayedFont
) return FALSE
;
2649 GtkWidget
*connect_widget
= GetConnectWidget();
2650 if (!connect_widget
->window
)
2652 // indicate that a new style has been set
2653 // but it couldn't get applied as the
2654 // widget hasn't been realized yet.
2655 m_delayedFont
= TRUE
;
2657 // pretend we have done something
2661 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2662 if ( sysbg
== m_backgroundColour
)
2664 m_backgroundColour
= wxNullColour
;
2666 m_backgroundColour
= sysbg
;
2676 void wxWindow::CaptureMouse()
2678 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2680 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
2682 GtkWidget
*connect_widget
= GetConnectWidget();
2683 if (!connect_widget
->window
) return;
2685 gtk_grab_add( connect_widget
);
2686 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2688 (GDK_BUTTON_PRESS_MASK
|
2689 GDK_BUTTON_RELEASE_MASK
|
2690 GDK_POINTER_MOTION_MASK
),
2697 void wxWindow::ReleaseMouse()
2699 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2701 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
2703 GtkWidget
*connect_widget
= GetConnectWidget();
2704 if (!connect_widget
->window
) return;
2706 gtk_grab_remove( connect_widget
);
2707 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2708 g_capturing
= FALSE
;
2711 bool wxWindow::IsRetained() const
2716 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2717 int range
, bool refresh
)
2719 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2721 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2723 m_hasScrolling
= TRUE
;
2725 if (orient
== wxHORIZONTAL
)
2727 float fpos
= (float)pos
;
2728 float frange
= (float)range
;
2729 float fthumb
= (float)thumbVisible
;
2730 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2731 if (fpos
< 0.0) fpos
= 0.0;
2733 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2734 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2736 SetScrollPos( orient
, pos
, refresh
);
2740 m_oldHorizontalPos
= fpos
;
2742 m_hAdjust
->lower
= 0.0;
2743 m_hAdjust
->upper
= frange
;
2744 m_hAdjust
->value
= fpos
;
2745 m_hAdjust
->step_increment
= 1.0;
2746 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2747 m_hAdjust
->page_size
= fthumb
;
2751 float fpos
= (float)pos
;
2752 float frange
= (float)range
;
2753 float fthumb
= (float)thumbVisible
;
2754 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2755 if (fpos
< 0.0) fpos
= 0.0;
2757 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2758 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2760 SetScrollPos( orient
, pos
, refresh
);
2764 m_oldVerticalPos
= fpos
;
2766 m_vAdjust
->lower
= 0.0;
2767 m_vAdjust
->upper
= frange
;
2768 m_vAdjust
->value
= fpos
;
2769 m_vAdjust
->step_increment
= 1.0;
2770 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2771 m_vAdjust
->page_size
= fthumb
;
2774 if (orient
== wxHORIZONTAL
)
2775 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2777 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2780 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2782 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2784 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2786 if (orient
== wxHORIZONTAL
)
2788 float fpos
= (float)pos
;
2789 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2790 if (fpos
< 0.0) fpos
= 0.0;
2791 m_oldHorizontalPos
= fpos
;
2793 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2794 m_hAdjust
->value
= fpos
;
2798 float fpos
= (float)pos
;
2799 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2800 if (fpos
< 0.0) fpos
= 0.0;
2801 m_oldVerticalPos
= fpos
;
2803 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2804 m_vAdjust
->value
= fpos
;
2807 if (!m_isScrolling
) /* prevent recursion */
2809 if (m_wxwindow
->window
)
2811 if (orient
== wxHORIZONTAL
)
2812 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2814 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2819 int wxWindow::GetScrollThumb( int orient
) const
2821 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2823 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2825 if (orient
== wxHORIZONTAL
)
2826 return (int)(m_hAdjust
->page_size
+0.5);
2828 return (int)(m_vAdjust
->page_size
+0.5);
2831 int wxWindow::GetScrollPos( int orient
) const
2833 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2835 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2837 if (orient
== wxHORIZONTAL
)
2838 return (int)(m_hAdjust
->value
+0.5);
2840 return (int)(m_vAdjust
->value
+0.5);
2843 int wxWindow::GetScrollRange( int orient
) const
2845 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
2847 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
2849 if (orient
== wxHORIZONTAL
)
2850 return (int)(m_hAdjust
->upper
+0.5);
2852 return (int)(m_vAdjust
->upper
+0.5);
2855 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2857 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2859 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2863 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2864 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2869 GetClientSize( &cw
, &ch
);
2870 int w
= cw
- abs(dx
);
2871 int h
= ch
- abs(dy
);
2873 if ((h
< 0) || (w
< 0))
2881 if (dx
< 0) s_x
= -dx
;
2882 if (dy
< 0) s_y
= -dy
;
2885 if (dx
> 0) d_x
= dx
;
2886 if (dy
> 0) d_y
= dy
;
2888 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2889 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2892 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2893 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2894 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2895 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2897 Refresh( TRUE
, &rect
);
2900 wxNode
*node
= m_children
.First();
2903 wxWindow
*child
= (wxWindow
*) node
->Data();
2904 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
2905 node
= node
->Next();
2909 void wxWindow::SetScrolling(bool scroll
)
2911 m_isScrolling
= g_blockEventsOnScroll
= scroll
;