1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "window.h"
16 #include "wx/window.h"
20 #include "wx/layout.h"
22 #include "wx/dialog.h"
23 #include "wx/msgdlg.h"
25 #if wxUSE_DRAG_AND_DROP
30 #include "wx/tooltip.h"
34 #include "wx/statusbr.h"
36 #include "wx/settings.h"
43 #include "gdk/gdkprivate.h"
44 #include "gdk/gdkkeysyms.h"
45 #include "wx/gtk/win_gtk.h"
49 //-----------------------------------------------------------------------------
50 // documentation on internals
51 //-----------------------------------------------------------------------------
54 I have been asked several times about writing some documentation about
55 the GTK port of wxWindows, especially its internal structures. Obviously,
56 you cannot understand wxGTK without knowing a little about the GTK, but
57 some more information about what the wxWindow, which is the base class
58 for all other window classes, does seems required as well.
60 What does wxWindow do? It contains the common interface for the following
61 jobs of its descendants:
63 1) Define the rudimentary behaviour common to all window classes, such as
64 resizing, intercepting user input (so as to make it possible to use these
65 events for special purposes in a derived class), window names etc.
67 2) Provide the possibility to contain and manage children, if the derived
68 class is allowed to contain children, which holds true for those window
69 classes which do not display a native GTK widget. To name them, these
70 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
71 work classes are a special case and are handled a bit differently from
72 the rest. The same holds true for the wxNotebook class.
74 3) Provide the possibility to draw into a client area of a window. This,
75 too, only holds true for classes that do not display a native GTK widget
78 4) Provide the entire mechanism for scrolling widgets. This actual inter-
79 face for this is usually in wxScrolledWindow, but the GTK implementation
82 5) A multitude of helper or extra methods for special purposes, such as
83 Drag'n'Drop, managing validators etc.
85 Normally one might expect, that one wxWindows window would always correspond
86 to one GTK widget. Under GTK, there is no such allround widget that has all
87 the functionality. Moreover, the GTK defines a client area as a different
88 widget from the actual widget you are handling. Last but not least some
89 special classes (e.g. wxFrame) handle different categories of widgets and
90 still have the possibility to draw something in the client area.
91 It was therefore required to write a special purpose GTK widget, that would
92 represent a client area in the sense of wxWindows capable to do the jobs
93 2), 3) and 4). I have written this class and it resides in win_gtk.c of
96 All windows must have a widget, with which they interact with other under-
97 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
98 thw wxWindow class has a member variable called m_widget which holds a
99 pointer to this widget. When the window class represents a GTK native widget,
100 this is (in most cases) the only GTK widget the class manages. E.g. the
101 wxStatitText class handles only a GtkLabel widget a pointer to which you
102 can find in m_widget (defined in wxWindow)
104 When the class has a client area for drawing into and for containing children
105 it has to handle the client area widget (of the type GtkMyFixed, defined in
106 win_gtk.c), but there could be any number of widgets, handled by a class
107 The common rule for all windows is only, that the widget that interacts with
108 the rest of GTK must be referenced in m_widget and all other widgets must be
109 children of this widget on the GTK level. The top-most widget, which also
110 represents the client area, must be in the m_wxwindow field and must be of
113 As I said, the window classes that display a GTK native widget only have
114 one widget, so in the case of e.g. the wxButton class m_widget holds a
115 pointer to a GtkButton widget. But windows with client areas (for drawing
116 and children) have a m_widget field that is a pointer to a GtkScrolled-
117 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
118 one is (in the GTK sense) a child of the GtkScrolledWindow.
120 If the m_wxwindow field is set, then all input to this widget is inter-
121 cepted and sent to the wxWindows class. If not, all input to the widget
122 that gets pointed to by m_widget gets intercepted and sent to the class.
126 //-----------------------------------------------------------------------------
128 //-----------------------------------------------------------------------------
130 extern wxList wxPendingDelete
;
131 extern bool g_blockEventsOnDrag
;
132 extern bool g_blockEventsOnScroll
;
133 extern wxCursor g_globalCursor
;
134 static wxWindow
*g_captureWindow
= (wxWindow
*) NULL
;
135 wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
137 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
138 the last click here */
139 static guint32 gs_timeLastClick
= 0;
141 //-----------------------------------------------------------------------------
143 //-----------------------------------------------------------------------------
147 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
148 GdkEvent
*WXUNUSED(event
),
152 static bool s_done = FALSE;
155 wxLog::AddTraceMask("focus");
158 wxLogTrace(_T("FOCUS NOW AT: %s"), name);
164 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
170 wxChar
*s
= new wxChar
[tmp
.Length()+1];
174 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
175 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
180 //-----------------------------------------------------------------------------
181 // missing gdk functions
182 //-----------------------------------------------------------------------------
185 gdk_window_warp_pointer (GdkWindow
*window
,
189 GdkWindowPrivate
*priv
;
192 window
= (GdkWindow
*) &gdk_root_parent
;
194 priv
= (GdkWindowPrivate
*) window
;
196 if (!priv
->destroyed
)
198 XWarpPointer (priv
->xdisplay
,
199 None
, /* not source window -> move from anywhere */
200 priv
->xwindow
, /* dest window */
201 0, 0, 0, 0, /* not source window -> move from anywhere */
206 //-----------------------------------------------------------------------------
208 //-----------------------------------------------------------------------------
210 extern void wxapp_install_idle_handler();
211 extern bool g_isIdle
;
213 //-----------------------------------------------------------------------------
214 // key event conversion routines
215 //-----------------------------------------------------------------------------
217 #if (GTK_MINOR_VERSION == 0)
218 /* these functions are copied verbatim from GTK 1.2 */
220 gdkx_XConvertCase (KeySym symbol
,
224 register KeySym sym
= symbol
;
226 g_return_if_fail (lower
!= NULL
);
227 g_return_if_fail (upper
!= NULL
);
234 #if defined (GDK_A) && defined (GDK_Ooblique)
235 case 0: /* Latin 1 */
236 if ((sym
>= GDK_A
) && (sym
<= GDK_Z
))
237 *lower
+= (GDK_a
- GDK_A
);
238 else if ((sym
>= GDK_a
) && (sym
<= GDK_z
))
239 *upper
-= (GDK_a
- GDK_A
);
240 else if ((sym
>= GDK_Agrave
) && (sym
<= GDK_Odiaeresis
))
241 *lower
+= (GDK_agrave
- GDK_Agrave
);
242 else if ((sym
>= GDK_agrave
) && (sym
<= GDK_odiaeresis
))
243 *upper
-= (GDK_agrave
- GDK_Agrave
);
244 else if ((sym
>= GDK_Ooblique
) && (sym
<= GDK_Thorn
))
245 *lower
+= (GDK_oslash
- GDK_Ooblique
);
246 else if ((sym
>= GDK_oslash
) && (sym
<= GDK_thorn
))
247 *upper
-= (GDK_oslash
- GDK_Ooblique
);
251 #if defined (GDK_Aogonek) && defined (GDK_tcedilla)
252 case 1: /* Latin 2 */
253 /* Assume the KeySym is a legal value (ignore discontinuities) */
254 if (sym
== GDK_Aogonek
)
255 *lower
= GDK_aogonek
;
256 else if (sym
>= GDK_Lstroke
&& sym
<= GDK_Sacute
)
257 *lower
+= (GDK_lstroke
- GDK_Lstroke
);
258 else if (sym
>= GDK_Scaron
&& sym
<= GDK_Zacute
)
259 *lower
+= (GDK_scaron
- GDK_Scaron
);
260 else if (sym
>= GDK_Zcaron
&& sym
<= GDK_Zabovedot
)
261 *lower
+= (GDK_zcaron
- GDK_Zcaron
);
262 else if (sym
== GDK_aogonek
)
263 *upper
= GDK_Aogonek
;
264 else if (sym
>= GDK_lstroke
&& sym
<= GDK_sacute
)
265 *upper
-= (GDK_lstroke
- GDK_Lstroke
);
266 else if (sym
>= GDK_scaron
&& sym
<= GDK_zacute
)
267 *upper
-= (GDK_scaron
- GDK_Scaron
);
268 else if (sym
>= GDK_zcaron
&& sym
<= GDK_zabovedot
)
269 *upper
-= (GDK_zcaron
- GDK_Zcaron
);
270 else if (sym
>= GDK_Racute
&& sym
<= GDK_Tcedilla
)
271 *lower
+= (GDK_racute
- GDK_Racute
);
272 else if (sym
>= GDK_racute
&& sym
<= GDK_tcedilla
)
273 *upper
-= (GDK_racute
- GDK_Racute
);
277 #if defined (GDK_Hstroke) && defined (GDK_Cabovedot)
278 case 2: /* Latin 3 */
279 /* Assume the KeySym is a legal value (ignore discontinuities) */
280 if (sym
>= GDK_Hstroke
&& sym
<= GDK_Hcircumflex
)
281 *lower
+= (GDK_hstroke
- GDK_Hstroke
);
282 else if (sym
>= GDK_Gbreve
&& sym
<= GDK_Jcircumflex
)
283 *lower
+= (GDK_gbreve
- GDK_Gbreve
);
284 else if (sym
>= GDK_hstroke
&& sym
<= GDK_hcircumflex
)
285 *upper
-= (GDK_hstroke
- GDK_Hstroke
);
286 else if (sym
>= GDK_gbreve
&& sym
<= GDK_jcircumflex
)
287 *upper
-= (GDK_gbreve
- GDK_Gbreve
);
288 else if (sym
>= GDK_Cabovedot
&& sym
<= GDK_Scircumflex
)
289 *lower
+= (GDK_cabovedot
- GDK_Cabovedot
);
290 else if (sym
>= GDK_cabovedot
&& sym
<= GDK_scircumflex
)
291 *upper
-= (GDK_cabovedot
- GDK_Cabovedot
);
295 #if defined (GDK_Rcedilla) && defined (GDK_Amacron)
296 case 3: /* Latin 4 */
297 /* Assume the KeySym is a legal value (ignore discontinuities) */
298 if (sym
>= GDK_Rcedilla
&& sym
<= GDK_Tslash
)
299 *lower
+= (GDK_rcedilla
- GDK_Rcedilla
);
300 else if (sym
>= GDK_rcedilla
&& sym
<= GDK_tslash
)
301 *upper
-= (GDK_rcedilla
- GDK_Rcedilla
);
302 else if (sym
== GDK_ENG
)
304 else if (sym
== GDK_eng
)
306 else if (sym
>= GDK_Amacron
&& sym
<= GDK_Umacron
)
307 *lower
+= (GDK_amacron
- GDK_Amacron
);
308 else if (sym
>= GDK_amacron
&& sym
<= GDK_umacron
)
309 *upper
-= (GDK_amacron
- GDK_Amacron
);
313 #if defined (GDK_Serbian_DJE) && defined (GDK_Cyrillic_yu)
314 case 6: /* Cyrillic */
315 /* Assume the KeySym is a legal value (ignore discontinuities) */
316 if (sym
>= GDK_Serbian_DJE
&& sym
<= GDK_Serbian_DZE
)
317 *lower
-= (GDK_Serbian_DJE
- GDK_Serbian_dje
);
318 else if (sym
>= GDK_Serbian_dje
&& sym
<= GDK_Serbian_dze
)
319 *upper
+= (GDK_Serbian_DJE
- GDK_Serbian_dje
);
320 else if (sym
>= GDK_Cyrillic_YU
&& sym
<= GDK_Cyrillic_HARDSIGN
)
321 *lower
-= (GDK_Cyrillic_YU
- GDK_Cyrillic_yu
);
322 else if (sym
>= GDK_Cyrillic_yu
&& sym
<= GDK_Cyrillic_hardsign
)
323 *upper
+= (GDK_Cyrillic_YU
- GDK_Cyrillic_yu
);
325 #endif /* CYRILLIC */
327 #if defined (GDK_Greek_ALPHAaccent) && defined (GDK_Greek_finalsmallsigma)
329 /* Assume the KeySym is a legal value (ignore discontinuities) */
330 if (sym
>= GDK_Greek_ALPHAaccent
&& sym
<= GDK_Greek_OMEGAaccent
)
331 *lower
+= (GDK_Greek_alphaaccent
- GDK_Greek_ALPHAaccent
);
332 else if (sym
>= GDK_Greek_alphaaccent
&& sym
<= GDK_Greek_omegaaccent
&&
333 sym
!= GDK_Greek_iotaaccentdieresis
&&
334 sym
!= GDK_Greek_upsilonaccentdieresis
)
335 *upper
-= (GDK_Greek_alphaaccent
- GDK_Greek_ALPHAaccent
);
336 else if (sym
>= GDK_Greek_ALPHA
&& sym
<= GDK_Greek_OMEGA
)
337 *lower
+= (GDK_Greek_alpha
- GDK_Greek_ALPHA
);
338 else if (sym
>= GDK_Greek_alpha
&& sym
<= GDK_Greek_omega
&&
339 sym
!= GDK_Greek_finalsmallsigma
)
340 *upper
-= (GDK_Greek_alpha
- GDK_Greek_ALPHA
);
347 gdk_keyval_to_upper (guint keyval
)
351 KeySym lower_val
= 0;
352 KeySym upper_val
= 0;
354 gdkx_XConvertCase (keyval
, &lower_val
, &upper_val
);
361 static long map_to_unmodified_wx_keysym( KeySym keysym
)
368 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
370 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
376 case GDK_Super_R
: key_code
= WXK_ALT
; break;
377 case GDK_Menu
: key_code
= WXK_MENU
; break;
378 case GDK_Help
: key_code
= WXK_HELP
; break;
379 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
380 case GDK_ISO_Left_Tab
:
381 case GDK_Tab
: key_code
= WXK_TAB
; break;
382 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
383 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
384 case GDK_Return
: key_code
= WXK_RETURN
; break;
385 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
386 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
387 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
388 case GDK_Delete
: key_code
= WXK_DELETE
; break;
389 case GDK_Home
: key_code
= WXK_HOME
; break;
390 case GDK_Left
: key_code
= WXK_LEFT
; break;
391 case GDK_Up
: key_code
= WXK_UP
; break;
392 case GDK_Right
: key_code
= WXK_RIGHT
; break;
393 case GDK_Down
: key_code
= WXK_DOWN
; break;
394 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
395 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
396 case GDK_Next
: key_code
= WXK_NEXT
; break;
397 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
398 case GDK_End
: key_code
= WXK_END
; break;
399 case GDK_Begin
: key_code
= WXK_HOME
; break;
400 case GDK_Select
: key_code
= WXK_SELECT
; break;
401 case GDK_Print
: key_code
= WXK_PRINT
; break;
402 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
403 case GDK_Insert
: key_code
= WXK_INSERT
; break;
404 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
406 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
407 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
408 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
409 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
410 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
411 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
412 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
413 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
414 case GDK_KP_8
: key_code
= WXK_NUMPAD8
; break;
415 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
416 case GDK_KP_Space
: key_code
= WXK_NUMPAD_SPACE
; break;
417 case GDK_KP_Tab
: key_code
= WXK_NUMPAD_TAB
; break;
418 case GDK_KP_Enter
: key_code
= WXK_NUMPAD_ENTER
; break;
419 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
420 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
421 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
422 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
423 case GDK_KP_Home
: key_code
= WXK_NUMPAD_HOME
; break;
424 case GDK_KP_Left
: key_code
= WXK_NUMPAD_LEFT
; break;
425 case GDK_KP_Up
: key_code
= WXK_NUMPAD_UP
; break;
426 case GDK_KP_Right
: key_code
= WXK_NUMPAD_RIGHT
; break;
427 case GDK_KP_Down
: key_code
= WXK_NUMPAD_DOWN
; break;
428 case GDK_KP_Prior
: key_code
= WXK_NUMPAD_PRIOR
; break;
429 // case GDK_KP_Page_Up: key_code = WXK_NUMPAD_PAGEUP; break;
430 case GDK_KP_Next
: key_code
= WXK_NUMPAD_NEXT
; break;
431 // case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break;
432 case GDK_KP_End
: key_code
= WXK_NUMPAD_END
; break;
433 case GDK_KP_Begin
: key_code
= WXK_NUMPAD_BEGIN
; break;
434 case GDK_KP_Insert
: key_code
= WXK_NUMPAD_INSERT
; break;
435 case GDK_KP_Delete
: key_code
= WXK_NUMPAD_DELETE
; break;
436 case GDK_KP_Equal
: key_code
= WXK_NUMPAD_EQUAL
; break;
437 case GDK_KP_Multiply
: key_code
= WXK_NUMPAD_MULTIPLY
; break;
438 case GDK_KP_Add
: key_code
= WXK_NUMPAD_ADD
; break;
439 case GDK_KP_Separator
: key_code
= WXK_NUMPAD_SEPARATOR
; break;
440 case GDK_KP_Subtract
: key_code
= WXK_NUMPAD_SUBTRACT
; break;
441 case GDK_KP_Decimal
: key_code
= WXK_NUMPAD_DECIMAL
; break;
442 case GDK_KP_Divide
: key_code
= WXK_NUMPAD_DIVIDE
; break;
444 case GDK_F1
: key_code
= WXK_F1
; break;
445 case GDK_F2
: key_code
= WXK_F2
; break;
446 case GDK_F3
: key_code
= WXK_F3
; break;
447 case GDK_F4
: key_code
= WXK_F4
; break;
448 case GDK_F5
: key_code
= WXK_F5
; break;
449 case GDK_F6
: key_code
= WXK_F6
; break;
450 case GDK_F7
: key_code
= WXK_F7
; break;
451 case GDK_F8
: key_code
= WXK_F8
; break;
452 case GDK_F9
: key_code
= WXK_F9
; break;
453 case GDK_F10
: key_code
= WXK_F10
; break;
454 case GDK_F11
: key_code
= WXK_F11
; break;
455 case GDK_F12
: key_code
= WXK_F12
; break;
460 guint upper
= gdk_keyval_to_upper( keysym
);
461 keysym
= (upper
!= 0 ? upper
: keysym
); /* to be MSW compatible */
470 static long map_to_wx_keysym( KeySym keysym
)
476 case GDK_Menu
: key_code
= WXK_MENU
; break;
477 case GDK_Help
: key_code
= WXK_HELP
; break;
478 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
479 case GDK_ISO_Left_Tab
:
480 case GDK_Tab
: key_code
= WXK_TAB
; break;
481 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
482 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
483 case GDK_Return
: key_code
= WXK_RETURN
; break;
484 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
485 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
486 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
487 case GDK_Delete
: key_code
= WXK_DELETE
; break;
488 case GDK_Home
: key_code
= WXK_HOME
; break;
489 case GDK_Left
: key_code
= WXK_LEFT
; break;
490 case GDK_Up
: key_code
= WXK_UP
; break;
491 case GDK_Right
: key_code
= WXK_RIGHT
; break;
492 case GDK_Down
: key_code
= WXK_DOWN
; break;
493 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
494 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
495 case GDK_Next
: key_code
= WXK_NEXT
; break;
496 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
497 case GDK_End
: key_code
= WXK_END
; break;
498 case GDK_Begin
: key_code
= WXK_HOME
; break;
499 case GDK_Select
: key_code
= WXK_SELECT
; break;
500 case GDK_Print
: key_code
= WXK_PRINT
; break;
501 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
502 case GDK_Insert
: key_code
= WXK_INSERT
; break;
503 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
505 case GDK_KP_0
: key_code
= '0'; break;
506 case GDK_KP_1
: key_code
= '1'; break;
507 case GDK_KP_2
: key_code
= '2'; break;
508 case GDK_KP_3
: key_code
= '3'; break;
509 case GDK_KP_4
: key_code
= '4'; break;
510 case GDK_KP_5
: key_code
= '5'; break;
511 case GDK_KP_6
: key_code
= '6'; break;
512 case GDK_KP_7
: key_code
= '7'; break;
513 case GDK_KP_8
: key_code
= '8'; break;
514 case GDK_KP_9
: key_code
= '9'; break;
515 case GDK_KP_Space
: key_code
= ' '; break;
516 case GDK_KP_Tab
: key_code
= WXK_TAB
; break; /* or '\t' ??? */
517 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break; /* or '\r' ??? */
518 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
519 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
520 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
521 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
522 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
523 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
524 case GDK_KP_Up
: key_code
= WXK_UP
; break;
525 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
526 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
527 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
528 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
529 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
530 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
531 case GDK_KP_End
: key_code
= WXK_END
; break;
532 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
533 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
534 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
535 case GDK_KP_Equal
: key_code
= '='; break;
536 case GDK_KP_Multiply
: key_code
= '*'; break;
537 case GDK_KP_Add
: key_code
= '+'; break;
538 case GDK_KP_Separator
: key_code
= ','; break;
539 case GDK_KP_Subtract
: key_code
= '-'; break;
540 case GDK_KP_Decimal
: key_code
= '.'; break;
541 case GDK_KP_Divide
: key_code
= '/'; break;
543 case GDK_F1
: key_code
= WXK_F1
; break;
544 case GDK_F2
: key_code
= WXK_F2
; break;
545 case GDK_F3
: key_code
= WXK_F3
; break;
546 case GDK_F4
: key_code
= WXK_F4
; break;
547 case GDK_F5
: key_code
= WXK_F5
; break;
548 case GDK_F6
: key_code
= WXK_F6
; break;
549 case GDK_F7
: key_code
= WXK_F7
; break;
550 case GDK_F8
: key_code
= WXK_F8
; break;
551 case GDK_F9
: key_code
= WXK_F9
; break;
552 case GDK_F10
: key_code
= WXK_F10
; break;
553 case GDK_F11
: key_code
= WXK_F11
; break;
554 case GDK_F12
: key_code
= WXK_F12
; break;
567 //-----------------------------------------------------------------------------
568 // local code (see below)
569 //-----------------------------------------------------------------------------
571 #if (GTK_MINOR_VERSION > 0)
573 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
581 if (win
->HasScrolling())
583 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
584 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
587 GtkWidget *hscrollbar = scroll_window->hscrollbar;
588 GtkWidget *vscrollbar = scroll_window->vscrollbar;
590 we use this instead: range.slider_width = 11 + 2*2pts edge
593 if (scroll_window
->vscrollbar_visible
)
595 dw
+= 15; /* dw += vscrollbar->allocation.width; */
596 dw
+= scroll_class
->scrollbar_spacing
;
599 if (scroll_window
->hscrollbar_visible
)
601 dh
+= 15; /* dh += hscrollbar->allocation.height; */
602 dh
+= scroll_class
->scrollbar_spacing
;
608 if (GTK_WIDGET_NO_WINDOW (widget
))
610 dx
+= widget
->allocation
.x
;
611 dy
+= widget
->allocation
.y
;
614 if (win
->HasFlag(wxRAISED_BORDER
))
616 gtk_draw_shadow( widget
->style
,
621 win
->m_width
-dw
, win
->m_height
-dh
);
625 if (win
->HasFlag(wxSUNKEN_BORDER
))
627 gtk_draw_shadow( widget
->style
,
632 win
->m_width
-dw
, win
->m_height
-dh
);
637 //-----------------------------------------------------------------------------
638 // "expose_event" of m_widget
639 //-----------------------------------------------------------------------------
641 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
643 if (gdk_event
->count
> 0) return;
644 draw_frame( widget
, win
);
647 //-----------------------------------------------------------------------------
648 // "draw" of m_wxwindow
649 //-----------------------------------------------------------------------------
651 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
653 draw_frame( widget
, win
);
656 #endif // GTK_MINOR_VERSION > 0
658 //-----------------------------------------------------------------------------
659 // "expose_event" of m_wxwindow
660 //-----------------------------------------------------------------------------
662 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
667 if (gdk_event
->window
!= win
->m_wxwindow
->window
)
670 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
672 gdk_event
->area
.width
,
673 gdk_event
->area
.height
);
675 if (gdk_event
->count
> 0)
678 wxPaintEvent
event( win
->GetId() );
679 event
.SetEventObject( win
);
680 win
->GetEventHandler()->ProcessEvent( event
);
683 wxPrintf( "OnExpose from " );
684 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
685 wxPrintf( win->GetClassInfo()->GetClassName() );
686 wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x,
687 (int)gdk_event->area.y,
688 (int)gdk_event->area.width,
689 (int)gdk_event->area.height );
692 win
->GetUpdateRegion().Clear();
695 //-----------------------------------------------------------------------------
696 // "draw" of m_wxwindow
697 //-----------------------------------------------------------------------------
699 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
702 wxapp_install_idle_handler();
707 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
708 rect
->width
, rect
->height
);
710 wxPaintEvent
event( win
->GetId() );
711 event
.SetEventObject( win
);
714 wxPrintf( "OnDraw from " );
715 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
716 printf( win->GetClassInfo()->GetClassName() );
717 wxPrintf( " %d %d %d %d\n", (int)rect->x,
723 win
->GetEventHandler()->ProcessEvent( event
);
725 win
->GetUpdateRegion().Clear();
728 //-----------------------------------------------------------------------------
729 // "key_press_event" from any window
730 //-----------------------------------------------------------------------------
732 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
735 wxapp_install_idle_handler();
737 if (!win
->m_hasVMT
) return FALSE
;
738 if (g_blockEventsOnDrag
) return FALSE
;
741 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
742 if (gdk_event->state & GDK_SHIFT_MASK)
743 printf( "ShiftDown.\n" );
745 printf( "ShiftUp.\n" );
746 if (gdk_event->state & GDK_CONTROL_MASK)
747 printf( "ControlDown.\n" );
749 printf( "ControlUp.\n" );
754 GdkModifierType state
;
755 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
757 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
759 /* sending unknown key events doesn't really make sense */
760 if (key_code
== 0) return FALSE
;
764 wxKeyEvent
event( wxEVT_KEY_DOWN
);
765 event
.SetTimestamp( gdk_event
->time
);
766 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
767 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
768 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
769 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
770 event
.m_keyCode
= key_code
;
771 event
.m_scanCode
= gdk_event
->keyval
;
774 event
.SetEventObject( win
);
775 ret
= win
->GetEventHandler()->ProcessEvent( event
);
777 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
782 wxWindow
*ancestor
= win
;
785 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
788 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
789 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
792 ancestor
= ancestor
->GetParent();
795 #endif // wxUSE_ACCEL
796 /* wxMSW doesn't send char events with Alt pressed */
797 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
798 will only be sent if it is not a menu accelerator. */
799 if ((key_code
!= 0) && ! ret
)
801 wxKeyEvent
event2( wxEVT_CHAR
);
802 event2
.SetTimestamp( gdk_event
->time
);
803 event2
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
804 event2
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
805 event2
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
806 event2
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
807 event2
.m_keyCode
= key_code
;
808 event2
.m_scanCode
= gdk_event
->keyval
;
811 event2
.SetEventObject( win
);
812 ret
= (ret
|| win
->GetEventHandler()->ProcessEvent( event2
));
815 /* win is a control: tab can be propagated up */
817 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
818 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
820 wxNavigationKeyEvent new_event
;
821 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
822 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
823 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
824 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
825 new_event
.SetCurrentFocus( win
);
826 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
829 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
831 (gdk_event
->keyval
== GDK_Escape
) )
833 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
834 new_event
.SetEventObject( win
);
835 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
838 #if (GTK_MINOR_VERSION > 0)
839 /* pressing F10 will activate the menu bar of the top frame */
841 (gdk_event
->keyval
== GDK_F10
) )
843 wxWindow
*ancestor
= win
;
846 if (wxIsKindOf(ancestor
,wxFrame
))
848 wxFrame
*frame
= (wxFrame
*) ancestor
;
849 wxMenuBar
*menubar
= frame
->GetMenuBar();
852 wxNode
*node
= menubar
->GetMenus().First();
855 // doesn't work correctly
856 // wxMenu *firstMenu = (wxMenu*) node->Data();
857 // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
863 ancestor
= ancestor
->GetParent();
869 Damn, I forgot why this didn't work, but it didn't work.
871 // win is a panel: up can be propagated to the panel
872 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
873 (gdk_event->keyval == GDK_Up))
875 win->m_parent->SetFocus();
879 // win is a panel: left/right can be propagated to the panel
880 if ((!ret) && (win->m_wxwindow) &&
881 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
882 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
884 wxNavigationKeyEvent new_event;
885 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
886 new_event.SetCurrentFocus( win );
887 ret = win->GetEventHandler()->ProcessEvent( new_event );
893 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
900 //-----------------------------------------------------------------------------
901 // "key_release_event" from any window
902 //-----------------------------------------------------------------------------
904 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
907 wxapp_install_idle_handler();
909 if (!win
->m_hasVMT
) return FALSE
;
910 if (g_blockEventsOnDrag
) return FALSE
;
913 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
914 if (gdk_event->state & GDK_SHIFT_MASK)
915 printf( "ShiftDown.\n" );
917 printf( "ShiftUp.\n" );
918 if (gdk_event->state & GDK_CONTROL_MASK)
919 printf( "ControlDown.\n" );
921 printf( "ControlUp.\n" );
925 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
927 /* sending unknown key events doesn't really make sense */
928 if (key_code
== 0) return FALSE
;
932 GdkModifierType state
;
933 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
935 wxKeyEvent
event( wxEVT_KEY_UP
);
936 event
.SetTimestamp( gdk_event
->time
);
937 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
938 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
939 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
940 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
941 event
.m_keyCode
= key_code
;
942 event
.m_scanCode
= gdk_event
->keyval
;
945 event
.SetEventObject( win
);
947 if (win
->GetEventHandler()->ProcessEvent( event
))
949 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
956 //-----------------------------------------------------------------------------
957 // "button_press_event"
958 //-----------------------------------------------------------------------------
960 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
963 wxapp_install_idle_handler();
966 wxPrintf( _T("1) OnButtonPress from ") );
967 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
968 wxPrintf( win->GetClassInfo()->GetClassName() );
969 wxPrintf( _T(".\n") );
971 if (!win
->m_hasVMT
) return FALSE
;
972 if (g_blockEventsOnDrag
) return TRUE
;
973 if (g_blockEventsOnScroll
) return TRUE
;
975 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
979 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
981 gtk_widget_grab_focus (win
->m_wxwindow
);
984 wxPrintf( _T("GrabFocus from ") );
985 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
986 wxPrintf( win->GetClassInfo()->GetClassName() );
987 wxPrintf( _T(".\n") );
994 wxPrintf( _T("2) OnButtonPress from ") );
995 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
996 wxPrintf( win->GetClassInfo()->GetClassName() );
997 wxPrintf( _T(".\n") );
1000 wxEventType event_type
= wxEVT_LEFT_DOWN
;
1002 if (gdk_event
->button
== 1)
1004 switch (gdk_event
->type
)
1006 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
1007 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
1011 else if (gdk_event
->button
== 2)
1013 switch (gdk_event
->type
)
1015 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
1016 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
1020 else if (gdk_event
->button
== 3)
1022 switch (gdk_event
->type
)
1024 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
1025 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
1030 wxMouseEvent
event( event_type
);
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
1046 if (!g_captureWindow
)
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 gs_timeLastClick
= gdk_event
->time
;
1101 if (win
->GetEventHandler()->ProcessEvent( event
))
1103 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
1110 //-----------------------------------------------------------------------------
1111 // "button_release_event"
1112 //-----------------------------------------------------------------------------
1114 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1117 wxapp_install_idle_handler();
1119 if (!win
->m_hasVMT
) return FALSE
;
1120 if (g_blockEventsOnDrag
) return FALSE
;
1121 if (g_blockEventsOnScroll
) return FALSE
;
1123 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1126 printf( "OnButtonRelease from " );
1127 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1128 printf( win->GetClassInfo()->GetClassName() );
1132 wxEventType event_type
= wxEVT_NULL
;
1134 switch (gdk_event
->button
)
1136 case 1: event_type
= wxEVT_LEFT_UP
; break;
1137 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
1138 case 3: event_type
= wxEVT_RIGHT_UP
; break;
1141 wxMouseEvent
event( event_type
);
1142 event
.SetTimestamp( gdk_event
->time
);
1143 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1144 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1145 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1146 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1147 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1148 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1149 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1150 event
.m_x
= (long)gdk_event
->x
;
1151 event
.m_y
= (long)gdk_event
->y
;
1153 // Some control don't have their own X window and thus cannot get
1156 if (!g_captureWindow
)
1158 wxNode
*node
= win
->GetChildren().First();
1161 wxWindow
*child
= (wxWindow
*)node
->Data();
1163 if (child
->m_isStaticBox
)
1165 // wxStaticBox is transparent in the box itself
1168 int xx1
= child
->m_x
;
1169 int yy1
= child
->m_y
;
1170 int xx2
= child
->m_x
+ child
->m_width
;
1171 int yy2
= child
->m_x
+ child
->m_height
;
1174 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1176 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1178 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1180 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1183 event
.m_x
-= child
->m_x
;
1184 event
.m_y
-= child
->m_y
;
1191 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1192 (child
->m_x
<= event
.m_x
) &&
1193 (child
->m_y
<= event
.m_y
) &&
1194 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1195 (child
->m_y
+child
->m_height
>= event
.m_y
))
1198 event
.m_x
-= child
->m_x
;
1199 event
.m_y
-= child
->m_y
;
1203 node
= node
->Next();
1207 event
.SetEventObject( win
);
1209 if (win
->GetEventHandler()->ProcessEvent( event
))
1211 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1218 //-----------------------------------------------------------------------------
1219 // "motion_notify_event"
1220 //-----------------------------------------------------------------------------
1222 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1225 wxapp_install_idle_handler();
1227 if (!win
->m_hasVMT
) return FALSE
;
1228 if (g_blockEventsOnDrag
) return FALSE
;
1229 if (g_blockEventsOnScroll
) return FALSE
;
1231 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1233 if (gdk_event
->is_hint
)
1237 GdkModifierType state
;
1238 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1241 gdk_event
->state
= state
;
1245 printf( "OnMotion from " );
1246 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1247 printf( win->GetClassInfo()->GetClassName() );
1251 wxMouseEvent
event( wxEVT_MOTION
);
1252 event
.SetTimestamp( gdk_event
->time
);
1253 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1254 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1255 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1256 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1257 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1258 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1259 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1261 event
.m_x
= (long)gdk_event
->x
;
1262 event
.m_y
= (long)gdk_event
->y
;
1264 // Some control don't have their own X window and thus cannot get
1267 if (!g_captureWindow
)
1269 wxNode
*node
= win
->GetChildren().First();
1272 wxWindow
*child
= (wxWindow
*)node
->Data();
1274 if (child
->m_isStaticBox
)
1276 // wxStaticBox is transparent in the box itself
1279 int xx1
= child
->m_x
;
1280 int yy1
= child
->m_y
;
1281 int xx2
= child
->m_x
+ child
->m_width
;
1282 int yy2
= child
->m_x
+ child
->m_height
;
1285 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1287 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1289 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1291 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1294 event
.m_x
-= child
->m_x
;
1295 event
.m_y
-= child
->m_y
;
1302 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1303 (child
->m_x
<= event
.m_x
) &&
1304 (child
->m_y
<= event
.m_y
) &&
1305 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1306 (child
->m_y
+child
->m_height
>= event
.m_y
))
1309 event
.m_x
-= child
->m_x
;
1310 event
.m_y
-= child
->m_y
;
1314 node
= node
->Next();
1318 event
.SetEventObject( win
);
1320 if (win
->GetEventHandler()->ProcessEvent( event
))
1322 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1329 //-----------------------------------------------------------------------------
1331 //-----------------------------------------------------------------------------
1333 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1336 wxapp_install_idle_handler();
1338 if (!win
->m_hasVMT
) return FALSE
;
1339 if (g_blockEventsOnDrag
) return FALSE
;
1341 g_focusWindow
= win
;
1343 if (win
->m_wxwindow
)
1345 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1347 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1349 printf( "SetFocus flag from " );
1350 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1351 printf( win->GetClassInfo()->GetClassName() );
1359 printf( "OnSetFocus from " );
1360 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1361 printf( win->GetClassInfo()->GetClassName() );
1363 printf( WXSTRINGCAST win->GetLabel() );
1367 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1368 event
.SetEventObject( win
);
1370 if (win
->GetEventHandler()->ProcessEvent( event
))
1372 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1379 //-----------------------------------------------------------------------------
1380 // "focus_out_event"
1381 //-----------------------------------------------------------------------------
1383 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1386 wxapp_install_idle_handler();
1388 if (!win
->m_hasVMT
) return FALSE
;
1389 if (g_blockEventsOnDrag
) return FALSE
;
1391 if (win
->m_wxwindow
)
1393 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1394 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1398 printf( "OnKillFocus from " );
1399 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1400 printf( win->GetClassInfo()->GetClassName() );
1404 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1405 event
.SetEventObject( win
);
1407 if (win
->GetEventHandler()->ProcessEvent( event
))
1409 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1416 //-----------------------------------------------------------------------------
1417 // "enter_notify_event"
1418 //-----------------------------------------------------------------------------
1420 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1423 wxapp_install_idle_handler();
1425 if (!win
->m_hasVMT
) return FALSE
;
1426 if (g_blockEventsOnDrag
) return FALSE
;
1428 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1430 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1431 #if (GTK_MINOR_VERSION > 0)
1432 event
.SetTimestamp( gdk_event
->time
);
1434 event
.SetEventObject( win
);
1438 GdkModifierType state
= (GdkModifierType
)0;
1440 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1442 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1443 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1444 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1445 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1446 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1447 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1448 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1450 event
.m_x
= (long)x
;
1451 event
.m_y
= (long)y
;
1453 if (win
->GetEventHandler()->ProcessEvent( event
))
1455 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1462 //-----------------------------------------------------------------------------
1463 // "leave_notify_event"
1464 //-----------------------------------------------------------------------------
1466 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1469 wxapp_install_idle_handler();
1471 if (!win
->m_hasVMT
) return FALSE
;
1472 if (g_blockEventsOnDrag
) return FALSE
;
1474 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1476 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1477 #if (GTK_MINOR_VERSION > 0)
1478 event
.SetTimestamp( gdk_event
->time
);
1480 event
.SetEventObject( win
);
1484 GdkModifierType state
= (GdkModifierType
)0;
1486 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1488 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1489 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1490 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1491 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1492 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1493 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1494 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1496 event
.m_x
= (long)x
;
1497 event
.m_y
= (long)y
;
1499 if (win
->GetEventHandler()->ProcessEvent( event
))
1501 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1508 //-----------------------------------------------------------------------------
1509 // "value_changed" from m_vAdjust
1510 //-----------------------------------------------------------------------------
1512 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1515 wxapp_install_idle_handler();
1517 if (g_blockEventsOnDrag
) return;
1519 if (!win
->m_hasVMT
) return;
1521 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1522 if (fabs(diff
) < 0.2) return;
1523 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1525 wxEventType command
= wxEVT_NULL
;
1527 float line_step
= win
->m_vAdjust
->step_increment
;
1528 float page_step
= win
->m_vAdjust
->page_increment
;
1530 if (win
->IsScrolling())
1532 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1536 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1537 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1538 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1539 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1540 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1541 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1542 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1545 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1547 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1548 event
.SetEventObject( win
);
1549 win
->GetEventHandler()->ProcessEvent( event
);
1552 //-----------------------------------------------------------------------------
1553 // "value_changed" from m_hAdjust
1554 //-----------------------------------------------------------------------------
1556 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1559 wxapp_install_idle_handler();
1561 if (g_blockEventsOnDrag
) return;
1562 if (!win
->m_hasVMT
) return;
1564 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1565 if (fabs(diff
) < 0.2) return;
1566 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1568 wxEventType command
= wxEVT_NULL
;
1570 float line_step
= win
->m_hAdjust
->step_increment
;
1571 float page_step
= win
->m_hAdjust
->page_increment
;
1573 if (win
->IsScrolling())
1575 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1579 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1580 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1581 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1582 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1583 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1584 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1585 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1588 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1590 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1591 event
.SetEventObject( win
);
1592 win
->GetEventHandler()->ProcessEvent( event
);
1595 //-----------------------------------------------------------------------------
1596 // "changed" from m_vAdjust
1597 //-----------------------------------------------------------------------------
1599 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1602 wxapp_install_idle_handler();
1604 if (g_blockEventsOnDrag
) return;
1605 if (!win
->m_hasVMT
) return;
1607 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1608 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1610 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1611 event
.SetEventObject( win
);
1612 win
->GetEventHandler()->ProcessEvent( event
);
1615 //-----------------------------------------------------------------------------
1616 // "changed" from m_hAdjust
1617 //-----------------------------------------------------------------------------
1619 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1622 wxapp_install_idle_handler();
1624 if (g_blockEventsOnDrag
) return;
1625 if (!win
->m_hasVMT
) return;
1627 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1628 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1630 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1631 event
.SetEventObject( win
);
1632 win
->GetEventHandler()->ProcessEvent( event
);
1635 //-----------------------------------------------------------------------------
1636 // "button_press_event" from scrollbar
1637 //-----------------------------------------------------------------------------
1639 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1640 GdkEventButton
*WXUNUSED(gdk_event
),
1644 wxapp_install_idle_handler();
1646 // don't test here as we can release the mouse while being over
1647 // a different window then the slider
1649 // if (gdk_event->window != widget->slider) return FALSE;
1651 win
->SetScrolling( TRUE
);
1656 //-----------------------------------------------------------------------------
1657 // "button_release_event" from scrollbar
1658 //-----------------------------------------------------------------------------
1660 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1661 GdkEventButton
*WXUNUSED(gdk_event
),
1665 // don't test here as we can release the mouse while being over
1666 // a different window then the slider
1668 // if (gdk_event->window != widget->slider) return FALSE;
1670 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1672 if (widget
== GTK_RANGE(scrolledWindow
->vscrollbar
))
1673 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1675 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1677 win
->SetScrolling( FALSE
);
1682 // ----------------------------------------------------------------------------
1683 // this wxWindowBase function is implemented here (in platform-specific file)
1684 // because it is static and so couldn't be made virtual
1685 // ----------------------------------------------------------------------------
1687 wxWindow
*wxWindowBase::FindFocus()
1689 return g_focusWindow
;
1692 //-----------------------------------------------------------------------------
1693 // "realize" from m_widget
1694 //-----------------------------------------------------------------------------
1696 /* we cannot set colours, fonts and cursors before the widget has
1697 been realized, so we do this directly after realization */
1700 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1703 wxapp_install_idle_handler();
1705 if (win
->m_delayedFont
)
1706 win
->SetFont( win
->GetFont() );
1708 if (win
->m_delayedBackgroundColour
)
1709 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1711 if (win
->m_delayedForegroundColour
)
1712 win
->SetForegroundColour( win
->GetForegroundColour() );
1714 win
->SetCursor( win
->GetCursor() );
1716 wxWindowCreateEvent
event( win
);
1717 event
.SetEventObject( win
);
1718 win
->GetEventHandler()->ProcessEvent( event
);
1723 //-----------------------------------------------------------------------------
1724 // InsertChild for wxWindow.
1725 //-----------------------------------------------------------------------------
1727 /* Callback for wxWindow. This very strange beast has to be used because
1728 * C++ has no virtual methods in a constructor. We have to emulate a
1729 * virtual function here as wxNotebook requires a different way to insert
1730 * a child in it. I had opted for creating a wxNotebookPage window class
1731 * which would have made this superfluous (such in the MDI window system),
1732 * but no-one was listening to me... */
1734 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1736 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1737 GTK_WIDGET(child
->m_widget
),
1743 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1745 /* we now allow a window to get the focus as long as it
1746 doesn't have any children. */
1747 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1751 //-----------------------------------------------------------------------------
1753 //-----------------------------------------------------------------------------
1755 wxWindow
* wxGetActiveWindow()
1757 return g_focusWindow
;
1760 //-----------------------------------------------------------------------------
1762 //-----------------------------------------------------------------------------
1764 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1766 void wxWindow::Init()
1772 m_widget
= (GtkWidget
*) NULL
;
1773 m_wxwindow
= (GtkWidget
*) NULL
;
1783 m_needParent
= TRUE
;
1784 m_isBeingDeleted
= FALSE
;
1786 m_hasScrolling
= FALSE
;
1787 m_isScrolling
= FALSE
;
1789 m_hAdjust
= (GtkAdjustment
*) NULL
;
1790 m_vAdjust
= (GtkAdjustment
*) NULL
;
1791 m_oldHorizontalPos
= 0.0;
1792 m_oldVerticalPos
= 0.0;
1795 m_scrollGC
= (GdkGC
*) NULL
;
1796 m_widgetStyle
= (GtkStyle
*) NULL
;
1798 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1800 m_isStaticBox
= FALSE
;
1801 m_isRadioButton
= FALSE
;
1802 m_acceptsFocus
= FALSE
;
1805 wxWindow::wxWindow()
1810 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1811 const wxPoint
&pos
, const wxSize
&size
,
1812 long style
, const wxString
&name
)
1816 Create( parent
, id
, pos
, size
, style
, name
);
1819 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1820 const wxPoint
&pos
, const wxSize
&size
,
1821 long style
, const wxString
&name
)
1823 if (!PreCreation( parent
, pos
, size
) ||
1824 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
1826 wxFAIL_MSG( _T("wxWindow creation failed") );
1830 m_insertCallback
= wxInsertChildInWindow
;
1832 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1833 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1836 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1839 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1842 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1843 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1846 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1847 scroll_class
->scrollbar_spacing
= 0;
1849 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1851 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1852 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1854 m_wxwindow
= gtk_myfixed_new();
1857 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1860 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1862 #if (GTK_MINOR_VERSION > 0)
1863 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1865 if (HasFlag(wxRAISED_BORDER
))
1867 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1869 else if (HasFlag(wxSUNKEN_BORDER
))
1871 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1875 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1877 #else // GTK_MINOR_VERSION == 0
1878 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1880 if (HasFlag(wxRAISED_BORDER
))
1882 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1884 else if (HasFlag(wxSUNKEN_BORDER
))
1886 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1890 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1892 #endif // GTK_MINOR_VERSION
1894 if (HasFlag(wxTAB_TRAVERSAL
))
1896 /* we now allow a window to get the focus as long as it
1897 doesn't have any children. */
1898 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1899 m_acceptsFocus
= FALSE
;
1903 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1904 m_acceptsFocus
= TRUE
;
1907 #if (GTK_MINOR_VERSION == 0)
1908 // shut the viewport up
1909 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1910 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1911 #endif // GTK_MINOR_VERSION == 0
1913 // I _really_ don't want scrollbars in the beginning
1914 m_vAdjust
->lower
= 0.0;
1915 m_vAdjust
->upper
= 1.0;
1916 m_vAdjust
->value
= 0.0;
1917 m_vAdjust
->step_increment
= 1.0;
1918 m_vAdjust
->page_increment
= 1.0;
1919 m_vAdjust
->page_size
= 5.0;
1920 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1921 m_hAdjust
->lower
= 0.0;
1922 m_hAdjust
->upper
= 1.0;
1923 m_hAdjust
->value
= 0.0;
1924 m_hAdjust
->step_increment
= 1.0;
1925 m_hAdjust
->page_increment
= 1.0;
1926 m_hAdjust
->page_size
= 5.0;
1927 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1929 // these handlers block mouse events to any window during scrolling such as
1930 // motion events and prevent GTK and wxWindows from fighting over where the
1933 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1934 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1936 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1937 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1939 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1940 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1942 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1943 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1945 // these handlers get notified when screen updates are required either when
1946 // scrolling or when the window size (and therefore scrollbar configuration)
1949 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1950 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1951 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1952 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1954 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1955 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1956 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1957 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1959 gtk_widget_show( m_wxwindow
);
1962 m_parent
->DoAddChild( this );
1971 wxWindow::~wxWindow()
1973 m_isBeingDeleted
= TRUE
;
1982 m_parent
->RemoveChild( this );
1986 gtk_style_unref( m_widgetStyle
);
1987 m_widgetStyle
= (GtkStyle
*) NULL
;
1992 gdk_gc_unref( m_scrollGC
);
1993 m_scrollGC
= (GdkGC
*) NULL
;
1998 gtk_widget_destroy( m_wxwindow
);
1999 m_wxwindow
= (GtkWidget
*) NULL
;
2004 gtk_widget_destroy( m_widget
);
2005 m_widget
= (GtkWidget
*) NULL
;
2009 bool wxWindow::PreCreation( wxWindow
*parent
, const wxPoint
&pos
, const wxSize
&size
)
2011 wxCHECK_MSG( !m_needParent
|| parent
, FALSE
, _T("Need complete parent.") );
2013 /* this turns -1 into 20 so that a minimal window is
2014 visible even although -1,-1 has been given as the
2015 size of the window. the same trick is used in other
2016 ports and should make debugging easier */
2017 m_width
= WidthDefault(size
.x
);
2018 m_height
= HeightDefault(size
.y
);
2023 /* some reasonable defaults */
2028 m_x
= (gdk_screen_width () - m_width
) / 2;
2029 if (m_x
< 10) m_x
= 10;
2033 m_y
= (gdk_screen_height () - m_height
) / 2;
2034 if (m_y
< 10) m_y
= 10;
2041 void wxWindow::PostCreation()
2043 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2047 /* these get reported to wxWindows -> wxPaintEvent */
2048 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
2049 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
2051 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
2052 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
2054 #if (GTK_MINOR_VERSION > 0)
2055 /* these are called when the "sunken" or "raised" borders are drawn */
2056 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
2057 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
2059 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
2060 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
2064 GtkWidget
*connect_widget
= GetConnectWidget();
2066 ConnectWidget( connect_widget
);
2068 /* we cannot set colours, fonts and cursors before the widget has
2069 been realized, so we do this directly after realization */
2070 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
2071 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
2076 void wxWindow::ConnectWidget( GtkWidget
*widget
)
2078 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
2079 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
2081 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
2082 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
2084 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
2085 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
2087 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
2088 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
2090 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
2091 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
2093 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
2094 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2096 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
2097 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2099 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
2100 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
2102 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
2103 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
2106 bool wxWindow::Destroy()
2108 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2112 return wxWindowBase::Destroy();
2115 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
2117 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2118 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
2120 if (m_resizing
) return; /* I don't like recursions */
2123 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
2125 /* don't set the size for children of wxNotebook, just take the values. */
2133 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
2135 if (x
!= -1) m_x
= x
;
2136 if (y
!= -1) m_y
= y
;
2137 if (width
!= -1) m_width
= width
;
2138 if (height
!= -1) m_height
= height
;
2148 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2150 if (width
== -1) m_width
= 80;
2153 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2155 if (height
== -1) m_height
= 26;
2158 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2159 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2160 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2161 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2164 int bottom_border
= 0;
2166 if (GTK_WIDGET_CAN_DEFAULT(m_widget
))
2168 /* the default button has a border around it */
2173 /* this is the result of hours of debugging: the following code
2174 means that if we have a m_wxwindow and we set the size of
2175 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
2176 automatically propagate its size down to its m_wxwindow,
2177 which is its client area. therefore, we have to tell the
2178 client area directly that it has to resize itself.
2179 this will lead to that m_widget (GtkScrolledWindow) will
2180 calculate how much size it needs for scrollbars etc and
2181 it will then call XXX_size_allocate of its child, which
2182 is m_wxwindow. m_wxwindow in turn will do the same with its
2183 children and so on. problems can arise if this happens
2184 before all the children have been realized as some widgets
2185 stupidy need to be realized during XXX_size_allocate (e.g.
2186 GtkNotebook) and they will segv if called otherwise. this
2187 emergency is tested in gtk_myfixed_size_allocate. Normally
2188 this shouldn't be needed and only gtk_widget_queue_resize()
2189 should be enough to provoke a resize at the next appropriate
2190 moment, but this seems to fail, e.g. when a wxNotebook contains
2191 a wxSplitterWindow: the splitter window's children won't
2192 show up properly resized then. */
2194 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
2199 m_height
+border
+bottom_border
);
2204 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2205 event
.SetEventObject( this );
2206 GetEventHandler()->ProcessEvent( event
);
2211 void wxWindow::OnInternalIdle()
2213 wxCursor cursor
= m_cursor
;
2214 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2216 if (cursor
.Ok() && m_currentGdkCursor
!= cursor
)
2218 m_currentGdkCursor
= cursor
;
2222 GdkWindow
*window
= m_wxwindow
->window
;
2224 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2226 if (!g_globalCursor
.Ok())
2227 cursor
= *wxSTANDARD_CURSOR
;
2229 window
= m_widget
->window
;
2231 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2235 GdkWindow
*window
= m_widget
->window
;
2237 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2244 void wxWindow::DoGetSize( int *width
, int *height
) const
2246 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2248 if (width
) (*width
) = m_width
;
2249 if (height
) (*height
) = m_height
;
2252 void wxWindow::DoSetClientSize( int width
, int height
)
2254 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2258 SetSize( width
, height
);
2265 #if (GTK_MINOR_VERSION == 0)
2266 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2270 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2271 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2273 GtkWidget
*viewport
= scroll_window
->viewport
;
2274 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2276 dw
+= 2 * viewport_class
->xthickness
;
2277 dh
+= 2 * viewport_class
->ythickness
;
2281 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2283 /* when using GTK 1.2 we set the border size to 2 */
2292 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2293 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2295 we use this instead: range.slider_width = 11 + 2*2pts edge
2298 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2299 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2301 if (scroll_window
->vscrollbar_visible
)
2303 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2304 dw
+= scroll_class
->scrollbar_spacing
;
2307 if (scroll_window
->hscrollbar_visible
)
2309 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2310 dh
+= scroll_class
->scrollbar_spacing
;
2314 SetSize( width
+dw
, height
+dh
);
2318 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2320 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2324 if (width
) (*width
) = m_width
;
2325 if (height
) (*height
) = m_height
;
2332 #if (GTK_MINOR_VERSION == 0)
2333 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2337 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2338 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2340 GtkWidget
*viewport
= scroll_window
->viewport
;
2341 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2343 dw
+= 2 * viewport_class
->xthickness
;
2344 dh
+= 2 * viewport_class
->ythickness
;
2348 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2350 /* when using GTK 1.2 we set the border size to 2 */
2358 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2359 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2361 we use this instead: range.slider_width = 11 + 2*2pts edge
2364 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2365 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2367 if (scroll_window
->vscrollbar_visible
)
2369 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2370 dw
+= scroll_class
->scrollbar_spacing
;
2373 if (scroll_window
->hscrollbar_visible
)
2375 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2376 dh
+= scroll_class
->scrollbar_spacing
;
2380 if (width
) (*width
) = m_width
- dw
;
2381 if (height
) (*height
) = m_height
- dh
;
2385 void wxWindow::DoGetPosition( int *x
, int *y
) const
2387 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2393 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2395 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2397 if (!m_widget
->window
) return;
2399 GdkWindow
*source
= (GdkWindow
*) NULL
;
2401 source
= m_wxwindow
->window
;
2403 source
= m_widget
->window
;
2407 gdk_window_get_origin( source
, &org_x
, &org_y
);
2411 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2413 org_x
+= m_widget
->allocation
.x
;
2414 org_y
+= m_widget
->allocation
.y
;
2422 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2424 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2426 if (!m_widget
->window
) return;
2428 GdkWindow
*source
= (GdkWindow
*) NULL
;
2430 source
= m_wxwindow
->window
;
2432 source
= m_widget
->window
;
2436 gdk_window_get_origin( source
, &org_x
, &org_y
);
2440 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2442 org_x
+= m_widget
->allocation
.x
;
2443 org_y
+= m_widget
->allocation
.y
;
2451 bool wxWindow::Show( bool show
)
2453 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2455 if (!wxWindowBase::Show(show
))
2462 gtk_widget_show( m_widget
);
2464 gtk_widget_hide( m_widget
);
2469 bool wxWindow::Enable( bool enable
)
2471 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2473 if (!wxWindowBase::Enable(enable
))
2479 gtk_widget_set_sensitive( m_widget
, enable
);
2481 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2486 int wxWindow::GetCharHeight() const
2488 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2490 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2492 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2494 return font
->ascent
+ font
->descent
;
2497 int wxWindow::GetCharWidth() const
2499 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2501 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2503 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2505 return gdk_string_width( font
, "H" );
2508 void wxWindow::GetTextExtent( const wxString
& string
,
2512 int *externalLeading
,
2513 const wxFont
*theFont
) const
2515 wxFont fontToUse
= m_font
;
2516 if (theFont
) fontToUse
= *theFont
;
2518 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2520 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2521 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2522 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2523 if (descent
) (*descent
) = font
->descent
;
2524 if (externalLeading
) (*externalLeading
) = 0; // ??
2527 void wxWindow::SetFocus()
2529 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2531 GtkWidget
*connect_widget
= GetConnectWidget();
2534 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2536 gtk_widget_grab_focus (connect_widget
);
2538 else if (GTK_IS_CONTAINER(connect_widget
))
2540 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2548 bool wxWindow::AcceptsFocus() const
2550 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2553 bool wxWindow::Reparent( wxWindow
*newParent
)
2555 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2557 wxWindow
*oldParent
= m_parent
;
2559 if ( !wxWindowBase::Reparent(newParent
) )
2564 gtk_container_remove( GTK_CONTAINER(oldParent
->m_wxwindow
), m_widget
);
2569 /* insert GTK representation */
2570 (*(newParent
->m_insertCallback
))(newParent
, this);
2576 void wxWindow::DoAddChild(wxWindow
*child
)
2578 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2580 wxASSERT_MSG( (child
!= NULL
), _T("invalid child window") );
2582 wxASSERT_MSG( (m_insertCallback
!= NULL
), _T("invalid child insertion function") );
2587 /* insert GTK representation */
2588 (*m_insertCallback
)(this, child
);
2591 void wxWindow::Raise()
2593 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2595 if (!m_widget
->window
) return;
2597 gdk_window_raise( m_widget
->window
);
2600 void wxWindow::Lower()
2602 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2604 if (!m_widget
->window
) return;
2606 gdk_window_lower( m_widget
->window
);
2609 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2611 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2613 if (!wxWindowBase::SetCursor(cursor
))
2615 // don't leave if the GTK widget has just
2617 if (!m_delayedCursor
) return FALSE
;
2620 GtkWidget
*connect_widget
= GetConnectWidget();
2621 if (!connect_widget
->window
)
2623 // indicate that a new style has been set
2624 // but it couldn't get applied as the
2625 // widget hasn't been realized yet.
2626 m_delayedCursor
= TRUE
;
2628 // pretend we have done something
2632 // gdk_window_set_cursor( connect_widget->window, GetCursor().GetCursor() );
2638 void wxWindow::WarpPointer( int x
, int y
)
2640 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2642 GtkWidget
*connect_widget
= GetConnectWidget();
2643 if (connect_widget
->window
)
2645 /* we provide this function ourselves as it is
2647 gdk_window_warp_pointer( connect_widget
->window
, x
, y
);
2651 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2653 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2655 if (!m_widget
->window
) return;
2657 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2661 gdk_window_clear_area( m_wxwindow
->window
,
2663 rect
->width
, rect
->height
);
2667 gdk_window_clear( m_wxwindow
->window
);
2674 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2676 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2680 GdkRectangle gdk_rect
;
2681 gdk_rect
.x
= rect
->x
;
2682 gdk_rect
.y
= rect
->y
;
2683 gdk_rect
.width
= rect
->width
;
2684 gdk_rect
.height
= rect
->height
;
2687 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2689 gtk_widget_draw( m_widget
, &gdk_rect
);
2693 void wxWindow::Clear()
2695 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2697 if (!m_widget
->window
) return;
2699 if (m_wxwindow
&& m_wxwindow
->window
)
2701 gdk_window_clear( m_wxwindow
->window
);
2706 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2708 wxWindowBase::DoSetToolTip(tip
);
2711 m_tooltip
->Apply( this );
2714 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2716 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2718 #endif // wxUSE_TOOLTIPS
2720 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2722 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2724 if (!wxWindowBase::SetBackgroundColour(colour
))
2726 // don't leave if the GTK widget has just
2728 if (!m_delayedBackgroundColour
) return FALSE
;
2731 GtkWidget
*connect_widget
= GetConnectWidget();
2732 if (!connect_widget
->window
)
2734 // indicate that a new style has been set
2735 // but it couldn't get applied as the
2736 // widget hasn't been realized yet.
2737 m_delayedBackgroundColour
= TRUE
;
2739 // pretend we have done something
2743 if (m_wxwindow
&& m_wxwindow
->window
)
2745 /* wxMSW doesn't clear the window here. I don't do that either to
2746 provide compatibility. call Clear() to do the job. */
2748 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2749 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2752 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2753 if (sysbg
== m_backgroundColour
)
2755 m_backgroundColour
= wxNullColour
;
2757 m_backgroundColour
= sysbg
;
2767 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2769 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2771 if (!wxWindowBase::SetForegroundColour(colour
))
2773 // don't leave if the GTK widget has just
2775 if (!m_delayedForegroundColour
) return FALSE
;
2778 GtkWidget
*connect_widget
= GetConnectWidget();
2779 if (!connect_widget
->window
)
2781 // indicate that a new style has been set
2782 // but it couldn't get applied as the
2783 // widget hasn't been realized yet.
2784 m_delayedForegroundColour
= TRUE
;
2786 // pretend we have done something
2790 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2791 if ( sysbg
== m_backgroundColour
)
2793 m_backgroundColour
= wxNullColour
;
2795 m_backgroundColour
= sysbg
;
2805 GtkStyle
*wxWindow::GetWidgetStyle()
2807 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2809 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2811 return m_widgetStyle
;
2814 void wxWindow::SetWidgetStyle()
2816 GtkStyle
*style
= GetWidgetStyle();
2818 gdk_font_unref( style
->font
);
2819 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2821 if (m_foregroundColour
.Ok())
2823 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2824 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2825 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2826 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2829 if (m_backgroundColour
.Ok())
2831 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2832 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2833 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2834 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2835 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2836 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2837 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2838 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2839 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2843 void wxWindow::ApplyWidgetStyle()
2847 //-----------------------------------------------------------------------------
2848 // Pop-up menu stuff
2849 //-----------------------------------------------------------------------------
2851 static void gtk_pop_hide_callback( GtkWidget
*WXUNUSED(widget
), bool* is_waiting
)
2853 *is_waiting
= FALSE
;
2856 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2858 menu
->SetInvokingWindow( win
);
2859 wxNode
*node
= menu
->GetItems().First();
2862 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2863 if (menuitem
->IsSubMenu())
2865 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2867 node
= node
->Next();
2871 static gint gs_pop_x
= 0;
2872 static gint gs_pop_y
= 0;
2874 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2878 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2883 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
2885 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2887 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2889 SetInvokingWindow( menu
, this );
2896 bool is_waiting
= TRUE
;
2898 gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide",
2899 GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting
);
2902 GTK_MENU(menu
->m_menu
),
2903 (GtkWidget
*) NULL
, // parent menu shell
2904 (GtkWidget
*) NULL
, // parent menu item
2905 (GtkMenuPositionFunc
) pop_pos_callback
,
2906 (gpointer
) this, // client data
2907 0, // button used to activate it
2908 0 //gs_timeLastClick // the time of activation
2913 while (gtk_events_pending())
2914 gtk_main_iteration();
2920 #if wxUSE_DRAG_AND_DROP
2922 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2924 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2926 GtkWidget
*dnd_widget
= GetConnectWidget();
2928 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2930 if (m_dropTarget
) delete m_dropTarget
;
2931 m_dropTarget
= dropTarget
;
2933 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2936 #endif // wxUSE_DRAG_AND_DROP
2938 GtkWidget
* wxWindow::GetConnectWidget()
2940 GtkWidget
*connect_widget
= m_widget
;
2941 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2943 return connect_widget
;
2946 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2948 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2949 return (window
== m_widget
->window
);
2952 bool wxWindow::SetFont( const wxFont
&font
)
2954 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T( "invalid window") );
2956 if (!wxWindowBase::SetFont(font
))
2958 // don't leave if the GTK widget has just
2960 if (!m_delayedFont
) return FALSE
;
2963 GtkWidget
*connect_widget
= GetConnectWidget();
2964 if (!connect_widget
->window
)
2966 // indicate that a new style has been set
2967 // but it couldn't get applied as the
2968 // widget hasn't been realized yet.
2969 m_delayedFont
= TRUE
;
2971 // pretend we have done something
2975 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2976 if ( sysbg
== m_backgroundColour
)
2978 m_backgroundColour
= wxNullColour
;
2980 m_backgroundColour
= sysbg
;
2990 void wxWindow::CaptureMouse()
2992 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2994 wxCHECK_RET( g_captureWindow
== NULL
, _T("CaptureMouse called twice") );
2996 GtkWidget
*connect_widget
= GetConnectWidget();
2997 if (!connect_widget
->window
) return;
2999 gdk_pointer_grab( connect_widget
->window
, FALSE
,
3001 (GDK_BUTTON_PRESS_MASK
|
3002 GDK_BUTTON_RELEASE_MASK
|
3003 GDK_POINTER_MOTION_MASK
),
3005 m_cursor
.GetCursor(),
3007 g_captureWindow
= this;
3010 void wxWindow::ReleaseMouse()
3012 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3014 wxCHECK_RET( g_captureWindow
, _T("ReleaseMouse called twice") );
3016 GtkWidget
*connect_widget
= GetConnectWidget();
3017 if (!connect_widget
->window
) return;
3019 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3020 g_captureWindow
= (wxWindow
*) NULL
;
3023 bool wxWindow::IsRetained() const
3028 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3029 int range
, bool refresh
)
3031 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3033 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3035 m_hasScrolling
= TRUE
;
3037 if (orient
== wxHORIZONTAL
)
3039 float fpos
= (float)pos
;
3040 float frange
= (float)range
;
3041 float fthumb
= (float)thumbVisible
;
3042 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3043 if (fpos
< 0.0) fpos
= 0.0;
3045 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3046 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3048 SetScrollPos( orient
, pos
, refresh
);
3052 m_oldHorizontalPos
= fpos
;
3054 m_hAdjust
->lower
= 0.0;
3055 m_hAdjust
->upper
= frange
;
3056 m_hAdjust
->value
= fpos
;
3057 m_hAdjust
->step_increment
= 1.0;
3058 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3059 m_hAdjust
->page_size
= fthumb
;
3063 float fpos
= (float)pos
;
3064 float frange
= (float)range
;
3065 float fthumb
= (float)thumbVisible
;
3066 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3067 if (fpos
< 0.0) fpos
= 0.0;
3069 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3070 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3072 SetScrollPos( orient
, pos
, refresh
);
3076 m_oldVerticalPos
= fpos
;
3078 m_vAdjust
->lower
= 0.0;
3079 m_vAdjust
->upper
= frange
;
3080 m_vAdjust
->value
= fpos
;
3081 m_vAdjust
->step_increment
= 1.0;
3082 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3083 m_vAdjust
->page_size
= fthumb
;
3086 if (orient
== wxHORIZONTAL
)
3087 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3089 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3092 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3094 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3096 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3098 if (orient
== wxHORIZONTAL
)
3100 float fpos
= (float)pos
;
3101 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3102 if (fpos
< 0.0) fpos
= 0.0;
3103 m_oldHorizontalPos
= fpos
;
3105 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3106 m_hAdjust
->value
= fpos
;
3110 float fpos
= (float)pos
;
3111 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3112 if (fpos
< 0.0) fpos
= 0.0;
3113 m_oldVerticalPos
= fpos
;
3115 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3116 m_vAdjust
->value
= fpos
;
3119 if (!m_isScrolling
) /* prevent recursion */
3121 if (m_wxwindow
->window
)
3123 if (orient
== wxHORIZONTAL
)
3124 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3126 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3131 int wxWindow::GetScrollThumb( int orient
) const
3133 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3135 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3137 if (orient
== wxHORIZONTAL
)
3138 return (int)(m_hAdjust
->page_size
+0.5);
3140 return (int)(m_vAdjust
->page_size
+0.5);
3143 int wxWindow::GetScrollPos( int orient
) const
3145 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3147 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3149 if (orient
== wxHORIZONTAL
)
3150 return (int)(m_hAdjust
->value
+0.5);
3152 return (int)(m_vAdjust
->value
+0.5);
3155 int wxWindow::GetScrollRange( int orient
) const
3157 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3159 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3161 if (orient
== wxHORIZONTAL
)
3162 return (int)(m_hAdjust
->upper
+0.5);
3164 return (int)(m_vAdjust
->upper
+0.5);
3167 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3169 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3171 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3175 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3176 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3179 wxNode
*node
= m_children
.First();
3182 wxWindow
*child
= (wxWindow
*) node
->Data();
3185 child
->GetSize( &sx
, &sy
);
3186 child
->SetSize( child
->m_x
+ dx
, child
->m_y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
3187 node
= node
->Next();
3192 GetClientSize( &cw
, &ch
);
3193 int w
= cw
- abs(dx
);
3194 int h
= ch
- abs(dy
);
3196 if ((h
< 0) || (w
< 0))
3204 if (dx
< 0) s_x
= -dx
;
3205 if (dy
< 0) s_y
= -dy
;
3208 if (dx
> 0) d_x
= dx
;
3209 if (dy
> 0) d_y
= dy
;
3211 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3212 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3215 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3216 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3217 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3218 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3220 Refresh( TRUE
, &rect
);
3224 void wxWindow::SetScrolling(bool scroll
)
3226 m_isScrolling
= g_blockEventsOnScroll
= scroll
;