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 static 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
)
664 if ( !win
->m_hasVMT
)
667 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
669 gdk_event
->area
.width
,
670 gdk_event
->area
.height
);
672 if ( gdk_event
->count
> 0 )
676 printf( "OnExpose from " );
677 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
678 printf( win->GetClassInfo()->GetClassName() );
682 wxPaintEvent
event( win
->GetId() );
683 event
.SetEventObject( win
);
684 win
->GetEventHandler()->ProcessEvent( event
);
686 win
->GetUpdateRegion().Clear();
689 //-----------------------------------------------------------------------------
690 // "draw" of m_wxwindow
691 //-----------------------------------------------------------------------------
693 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
696 wxapp_install_idle_handler();
701 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
702 rect
->width
, rect
->height
);
704 wxPaintEvent
event( win
->GetId() );
705 event
.SetEventObject( win
);
706 win
->GetEventHandler()->ProcessEvent( event
);
708 win
->GetUpdateRegion().Clear();
711 //-----------------------------------------------------------------------------
712 // "key_press_event" from any window
713 //-----------------------------------------------------------------------------
715 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
718 wxapp_install_idle_handler();
720 if (!win
->m_hasVMT
) return FALSE
;
721 if (g_blockEventsOnDrag
) return FALSE
;
724 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
725 if (gdk_event->state & GDK_SHIFT_MASK)
726 printf( "ShiftDown.\n" );
728 printf( "ShiftUp.\n" );
729 if (gdk_event->state & GDK_CONTROL_MASK)
730 printf( "ControlDown.\n" );
732 printf( "ControlUp.\n" );
737 GdkModifierType state
;
738 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
740 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
742 /* sending unknown key events doesn't really make sense */
743 if (key_code
== 0) return FALSE
;
747 wxKeyEvent
event( wxEVT_KEY_DOWN
);
748 event
.SetTimestamp( gdk_event
->time
);
749 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
750 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
751 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
752 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
753 event
.m_keyCode
= key_code
;
754 event
.m_scanCode
= gdk_event
->keyval
;
757 event
.SetEventObject( win
);
758 ret
= win
->GetEventHandler()->ProcessEvent( event
);
760 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
765 wxWindow
*ancestor
= win
;
768 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
771 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
772 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
775 ancestor
= ancestor
->GetParent();
778 #endif // wxUSE_ACCEL
779 /* wxMSW doesn't send char events with Alt pressed */
780 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
781 will only be sent if it is not a menu accelerator. */
782 if ((key_code
!= 0) && ! ret
)
784 wxKeyEvent
event2( wxEVT_CHAR
);
785 event2
.SetTimestamp( gdk_event
->time
);
786 event2
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
787 event2
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
788 event2
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
789 event2
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
790 event2
.m_keyCode
= key_code
;
791 event2
.m_scanCode
= gdk_event
->keyval
;
794 event2
.SetEventObject( win
);
795 ret
= (ret
|| win
->GetEventHandler()->ProcessEvent( event2
));
799 /* win is a control: tab can be propagated up */
801 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
802 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
804 wxNavigationKeyEvent new_event
;
805 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
806 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
807 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
808 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
809 new_event
.SetCurrentFocus( win
);
810 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
813 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
815 (gdk_event
->keyval
== GDK_Escape
) )
817 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
818 new_event
.SetEventObject( win
);
819 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
822 #if (GTK_MINOR_VERSION > 0)
823 /* pressing F10 will activate the menu bar of the top frame */
825 (gdk_event
->keyval
== GDK_F10
) )
827 wxWindow
*ancestor
= win
;
830 if (wxIsKindOf(ancestor
,wxFrame
))
832 wxFrame
*frame
= (wxFrame
*) ancestor
;
833 wxMenuBar
*menubar
= frame
->GetMenuBar();
836 wxNode
*node
= menubar
->GetMenus().First();
839 // doesn't work correctly
840 // wxMenu *firstMenu = (wxMenu*) node->Data();
841 // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
847 ancestor
= ancestor
->GetParent();
853 Damn, I forgot why this didn't work, but it didn't work.
855 // win is a panel: up can be propagated to the panel
856 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
857 (gdk_event->keyval == GDK_Up))
859 win->m_parent->SetFocus();
863 // win is a panel: left/right can be propagated to the panel
864 if ((!ret) && (win->m_wxwindow) &&
865 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
866 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
868 wxNavigationKeyEvent new_event;
869 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
870 new_event.SetCurrentFocus( win );
871 ret = win->GetEventHandler()->ProcessEvent( new_event );
877 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
884 //-----------------------------------------------------------------------------
885 // "key_release_event" from any window
886 //-----------------------------------------------------------------------------
888 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
891 wxapp_install_idle_handler();
893 if (!win
->m_hasVMT
) return FALSE
;
894 if (g_blockEventsOnDrag
) return FALSE
;
897 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
898 if (gdk_event->state & GDK_SHIFT_MASK)
899 printf( "ShiftDown.\n" );
901 printf( "ShiftUp.\n" );
902 if (gdk_event->state & GDK_CONTROL_MASK)
903 printf( "ControlDown.\n" );
905 printf( "ControlUp.\n" );
909 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
911 /* sending unknown key events doesn't really make sense */
912 if (key_code
== 0) return FALSE
;
916 GdkModifierType state
;
917 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
919 wxKeyEvent
event( wxEVT_KEY_UP
);
920 event
.SetTimestamp( gdk_event
->time
);
921 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
922 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
923 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
924 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
925 event
.m_keyCode
= key_code
;
926 event
.m_scanCode
= gdk_event
->keyval
;
929 event
.SetEventObject( win
);
931 if (win
->GetEventHandler()->ProcessEvent( event
))
933 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
940 //-----------------------------------------------------------------------------
941 // "button_press_event"
942 //-----------------------------------------------------------------------------
944 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
947 wxapp_install_idle_handler();
950 wxPrintf( _T("1) OnButtonPress from ") );
951 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
952 wxPrintf( win->GetClassInfo()->GetClassName() );
953 wxPrintf( _T(".\n") );
955 if (!win
->m_hasVMT
) return FALSE
;
956 if (g_blockEventsOnDrag
) return TRUE
;
957 if (g_blockEventsOnScroll
) return TRUE
;
959 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
963 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
965 gtk_widget_grab_focus (win
->m_wxwindow
);
968 wxPrintf( _T("GrabFocus from ") );
969 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
970 wxPrintf( win->GetClassInfo()->GetClassName() );
971 wxPrintf( _T(".\n") );
978 wxPrintf( _T("2) OnButtonPress from ") );
979 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
980 wxPrintf( win->GetClassInfo()->GetClassName() );
981 wxPrintf( _T(".\n") );
984 wxEventType event_type
= wxEVT_LEFT_DOWN
;
986 if (gdk_event
->button
== 1)
988 switch (gdk_event
->type
)
990 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
991 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
995 else if (gdk_event
->button
== 2)
997 switch (gdk_event
->type
)
999 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
1000 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
1004 else if (gdk_event
->button
== 3)
1006 switch (gdk_event
->type
)
1008 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
1009 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
1014 wxMouseEvent
event( event_type
);
1015 event
.SetTimestamp( gdk_event
->time
);
1016 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1017 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1018 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1019 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1020 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1021 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1022 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1024 event
.m_x
= (long)gdk_event
->x
;
1025 event
.m_y
= (long)gdk_event
->y
;
1027 // Some control don't have their own X window and thus cannot get
1030 if (!g_captureWindow
)
1032 wxNode
*node
= win
->GetChildren().First();
1035 wxWindow
*child
= (wxWindow
*)node
->Data();
1037 if (child
->m_isStaticBox
)
1039 // wxStaticBox is transparent in the box itself
1042 int xx1
= child
->m_x
;
1043 int yy1
= child
->m_y
;
1044 int xx2
= child
->m_x
+ child
->m_width
;
1045 int yy2
= child
->m_x
+ child
->m_height
;
1048 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1050 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1052 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1054 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1057 event
.m_x
-= child
->m_x
;
1058 event
.m_y
-= child
->m_y
;
1065 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1066 (child
->m_x
<= event
.m_x
) &&
1067 (child
->m_y
<= event
.m_y
) &&
1068 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1069 (child
->m_y
+child
->m_height
>= event
.m_y
))
1072 event
.m_x
-= child
->m_x
;
1073 event
.m_y
-= child
->m_y
;
1077 node
= node
->Next();
1081 event
.SetEventObject( win
);
1083 gs_timeLastClick
= gdk_event
->time
;
1085 if (win
->GetEventHandler()->ProcessEvent( event
))
1087 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
1094 //-----------------------------------------------------------------------------
1095 // "button_release_event"
1096 //-----------------------------------------------------------------------------
1098 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1101 wxapp_install_idle_handler();
1103 if (!win
->m_hasVMT
) return FALSE
;
1104 if (g_blockEventsOnDrag
) return FALSE
;
1105 if (g_blockEventsOnScroll
) return FALSE
;
1107 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1110 printf( "OnButtonRelease from " );
1111 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1112 printf( win->GetClassInfo()->GetClassName() );
1116 wxEventType event_type
= wxEVT_NULL
;
1118 switch (gdk_event
->button
)
1120 case 1: event_type
= wxEVT_LEFT_UP
; break;
1121 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
1122 case 3: event_type
= wxEVT_RIGHT_UP
; break;
1125 wxMouseEvent
event( event_type
);
1126 event
.SetTimestamp( gdk_event
->time
);
1127 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1128 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1129 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1130 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1131 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1132 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1133 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1134 event
.m_x
= (long)gdk_event
->x
;
1135 event
.m_y
= (long)gdk_event
->y
;
1137 // Some control don't have their own X window and thus cannot get
1140 if (!g_captureWindow
)
1142 wxNode
*node
= win
->GetChildren().First();
1145 wxWindow
*child
= (wxWindow
*)node
->Data();
1147 if (child
->m_isStaticBox
)
1149 // wxStaticBox is transparent in the box itself
1152 int xx1
= child
->m_x
;
1153 int yy1
= child
->m_y
;
1154 int xx2
= child
->m_x
+ child
->m_width
;
1155 int yy2
= child
->m_x
+ child
->m_height
;
1158 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1160 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1162 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1164 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1167 event
.m_x
-= child
->m_x
;
1168 event
.m_y
-= child
->m_y
;
1175 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1176 (child
->m_x
<= event
.m_x
) &&
1177 (child
->m_y
<= event
.m_y
) &&
1178 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1179 (child
->m_y
+child
->m_height
>= event
.m_y
))
1182 event
.m_x
-= child
->m_x
;
1183 event
.m_y
-= child
->m_y
;
1187 node
= node
->Next();
1191 event
.SetEventObject( win
);
1193 if (win
->GetEventHandler()->ProcessEvent( event
))
1195 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1202 //-----------------------------------------------------------------------------
1203 // "motion_notify_event"
1204 //-----------------------------------------------------------------------------
1206 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1209 wxapp_install_idle_handler();
1211 if (!win
->m_hasVMT
) return FALSE
;
1212 if (g_blockEventsOnDrag
) return FALSE
;
1213 if (g_blockEventsOnScroll
) return FALSE
;
1215 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1217 if (gdk_event
->is_hint
)
1221 GdkModifierType state
;
1222 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1225 gdk_event
->state
= state
;
1229 printf( "OnMotion from " );
1230 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1231 printf( win->GetClassInfo()->GetClassName() );
1235 wxMouseEvent
event( wxEVT_MOTION
);
1236 event
.SetTimestamp( gdk_event
->time
);
1237 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1238 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1239 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1240 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1241 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1242 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1243 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1245 event
.m_x
= (long)gdk_event
->x
;
1246 event
.m_y
= (long)gdk_event
->y
;
1248 // Some control don't have their own X window and thus cannot get
1251 if (!g_captureWindow
)
1253 wxNode
*node
= win
->GetChildren().First();
1256 wxWindow
*child
= (wxWindow
*)node
->Data();
1258 if (child
->m_isStaticBox
)
1260 // wxStaticBox is transparent in the box itself
1263 int xx1
= child
->m_x
;
1264 int yy1
= child
->m_y
;
1265 int xx2
= child
->m_x
+ child
->m_width
;
1266 int yy2
= child
->m_x
+ child
->m_height
;
1269 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1271 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1273 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1275 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1278 event
.m_x
-= child
->m_x
;
1279 event
.m_y
-= child
->m_y
;
1286 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1287 (child
->m_x
<= event
.m_x
) &&
1288 (child
->m_y
<= event
.m_y
) &&
1289 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1290 (child
->m_y
+child
->m_height
>= event
.m_y
))
1293 event
.m_x
-= child
->m_x
;
1294 event
.m_y
-= child
->m_y
;
1298 node
= node
->Next();
1302 event
.SetEventObject( win
);
1304 if (win
->GetEventHandler()->ProcessEvent( event
))
1306 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1313 //-----------------------------------------------------------------------------
1315 //-----------------------------------------------------------------------------
1317 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1320 wxapp_install_idle_handler();
1322 if (!win
->m_hasVMT
) return FALSE
;
1323 if (g_blockEventsOnDrag
) return FALSE
;
1325 g_focusWindow
= win
;
1327 if (win
->m_wxwindow
)
1329 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1331 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1333 printf( "SetFocus flag from " );
1334 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1335 printf( win->GetClassInfo()->GetClassName() );
1343 printf( "OnSetFocus from " );
1344 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1345 printf( win->GetClassInfo()->GetClassName() );
1347 printf( WXSTRINGCAST win->GetLabel() );
1351 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1352 event
.SetEventObject( win
);
1354 if (win
->GetEventHandler()->ProcessEvent( event
))
1356 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1363 //-----------------------------------------------------------------------------
1364 // "focus_out_event"
1365 //-----------------------------------------------------------------------------
1367 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1370 wxapp_install_idle_handler();
1372 if (!win
->m_hasVMT
) return FALSE
;
1373 if (g_blockEventsOnDrag
) return FALSE
;
1375 if (win
->m_wxwindow
)
1377 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1378 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1382 printf( "OnKillFocus from " );
1383 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1384 printf( win->GetClassInfo()->GetClassName() );
1388 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1389 event
.SetEventObject( win
);
1391 if (win
->GetEventHandler()->ProcessEvent( event
))
1393 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1400 //-----------------------------------------------------------------------------
1401 // "enter_notify_event"
1402 //-----------------------------------------------------------------------------
1404 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1407 wxapp_install_idle_handler();
1409 if (!win
->m_hasVMT
) return FALSE
;
1410 if (g_blockEventsOnDrag
) return FALSE
;
1412 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1414 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1415 #if (GTK_MINOR_VERSION > 0)
1416 event
.SetTimestamp( gdk_event
->time
);
1418 event
.SetEventObject( win
);
1422 GdkModifierType state
= (GdkModifierType
)0;
1424 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1426 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1427 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1428 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1429 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1430 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1431 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1432 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1434 event
.m_x
= (long)x
;
1435 event
.m_y
= (long)y
;
1437 if (win
->GetEventHandler()->ProcessEvent( event
))
1439 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1446 //-----------------------------------------------------------------------------
1447 // "leave_notify_event"
1448 //-----------------------------------------------------------------------------
1450 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1453 wxapp_install_idle_handler();
1455 if (!win
->m_hasVMT
) return FALSE
;
1456 if (g_blockEventsOnDrag
) return FALSE
;
1458 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1460 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1461 #if (GTK_MINOR_VERSION > 0)
1462 event
.SetTimestamp( gdk_event
->time
);
1464 event
.SetEventObject( win
);
1468 GdkModifierType state
= (GdkModifierType
)0;
1470 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1472 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1473 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1474 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1475 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1476 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1477 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1478 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1480 event
.m_x
= (long)x
;
1481 event
.m_y
= (long)y
;
1483 if (win
->GetEventHandler()->ProcessEvent( event
))
1485 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1492 //-----------------------------------------------------------------------------
1493 // "value_changed" from m_vAdjust
1494 //-----------------------------------------------------------------------------
1496 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1499 wxapp_install_idle_handler();
1501 if (g_blockEventsOnDrag
) return;
1503 if (!win
->m_hasVMT
) return;
1505 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1506 if (fabs(diff
) < 0.2) return;
1507 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1509 wxEventType command
= wxEVT_NULL
;
1511 float line_step
= win
->m_vAdjust
->step_increment
;
1512 float page_step
= win
->m_vAdjust
->page_increment
;
1514 if (win
->IsScrolling())
1516 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1520 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1521 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1522 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1523 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1524 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1525 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1526 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1529 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1531 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1532 event
.SetEventObject( win
);
1533 win
->GetEventHandler()->ProcessEvent( event
);
1536 //-----------------------------------------------------------------------------
1537 // "value_changed" from m_hAdjust
1538 //-----------------------------------------------------------------------------
1540 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1543 wxapp_install_idle_handler();
1545 if (g_blockEventsOnDrag
) return;
1546 if (!win
->m_hasVMT
) return;
1548 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1549 if (fabs(diff
) < 0.2) return;
1550 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1552 wxEventType command
= wxEVT_NULL
;
1554 float line_step
= win
->m_hAdjust
->step_increment
;
1555 float page_step
= win
->m_hAdjust
->page_increment
;
1557 if (win
->IsScrolling())
1559 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1563 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1564 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1565 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1566 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1567 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1568 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1569 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1572 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1574 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1575 event
.SetEventObject( win
);
1576 win
->GetEventHandler()->ProcessEvent( event
);
1579 //-----------------------------------------------------------------------------
1580 // "changed" from m_vAdjust
1581 //-----------------------------------------------------------------------------
1583 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1586 wxapp_install_idle_handler();
1588 if (g_blockEventsOnDrag
) return;
1589 if (!win
->m_hasVMT
) return;
1591 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1592 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1594 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1595 event
.SetEventObject( win
);
1596 win
->GetEventHandler()->ProcessEvent( event
);
1599 //-----------------------------------------------------------------------------
1600 // "changed" from m_hAdjust
1601 //-----------------------------------------------------------------------------
1603 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1606 wxapp_install_idle_handler();
1608 if (g_blockEventsOnDrag
) return;
1609 if (!win
->m_hasVMT
) return;
1611 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1612 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1614 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1615 event
.SetEventObject( win
);
1616 win
->GetEventHandler()->ProcessEvent( event
);
1619 //-----------------------------------------------------------------------------
1620 // "button_press_event" from scrollbar
1621 //-----------------------------------------------------------------------------
1623 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1624 GdkEventButton
*WXUNUSED(gdk_event
),
1628 wxapp_install_idle_handler();
1630 // don't test here as we can release the mouse while being over
1631 // a different window then the slider
1633 // if (gdk_event->window != widget->slider) return FALSE;
1635 win
->SetScrolling( TRUE
);
1640 //-----------------------------------------------------------------------------
1641 // "button_release_event" from scrollbar
1642 //-----------------------------------------------------------------------------
1644 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1645 GdkEventButton
*WXUNUSED(gdk_event
),
1649 // don't test here as we can release the mouse while being over
1650 // a different window then the slider
1652 // if (gdk_event->window != widget->slider) return FALSE;
1654 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1656 if (widget
== GTK_RANGE(scrolledWindow
->vscrollbar
))
1657 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1659 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1661 win
->SetScrolling( FALSE
);
1666 // ----------------------------------------------------------------------------
1667 // this wxWindowBase function is implemented here (in platform-specific file)
1668 // because it is static and so couldn't be made virtual
1669 // ----------------------------------------------------------------------------
1671 wxWindow
*wxWindowBase::FindFocus()
1673 return g_focusWindow
;
1676 //-----------------------------------------------------------------------------
1677 // "realize" from m_widget
1678 //-----------------------------------------------------------------------------
1680 /* we cannot set colours, fonts and cursors before the widget has
1681 been realized, so we do this directly after realization */
1684 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1687 wxapp_install_idle_handler();
1689 if (win
->m_delayedFont
)
1690 win
->SetFont( win
->GetFont() );
1692 if (win
->m_delayedBackgroundColour
)
1693 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1695 if (win
->m_delayedForegroundColour
)
1696 win
->SetForegroundColour( win
->GetForegroundColour() );
1698 win
->SetCursor( win
->GetCursor() );
1700 wxWindowCreateEvent
event( win
);
1701 event
.SetEventObject( win
);
1702 win
->GetEventHandler()->ProcessEvent( event
);
1707 //-----------------------------------------------------------------------------
1708 // InsertChild for wxWindow.
1709 //-----------------------------------------------------------------------------
1711 /* Callback for wxWindow. This very strange beast has to be used because
1712 * C++ has no virtual methods in a constructor. We have to emulate a
1713 * virtual function here as wxNotebook requires a different way to insert
1714 * a child in it. I had opted for creating a wxNotebookPage window class
1715 * which would have made this superfluous (such in the MDI window system),
1716 * but no-one was listening to me... */
1718 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1720 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1721 GTK_WIDGET(child
->m_widget
),
1727 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1729 /* we now allow a window to get the focus as long as it
1730 doesn't have any children. */
1731 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1735 //-----------------------------------------------------------------------------
1737 //-----------------------------------------------------------------------------
1739 wxWindow
* wxGetActiveWindow()
1741 return g_focusWindow
;
1744 //-----------------------------------------------------------------------------
1746 //-----------------------------------------------------------------------------
1748 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1750 void wxWindow::Init()
1756 m_widget
= (GtkWidget
*) NULL
;
1757 m_wxwindow
= (GtkWidget
*) NULL
;
1767 m_needParent
= TRUE
;
1768 m_isBeingDeleted
= FALSE
;
1770 m_hasScrolling
= FALSE
;
1771 m_isScrolling
= FALSE
;
1773 m_hAdjust
= (GtkAdjustment
*) NULL
;
1774 m_vAdjust
= (GtkAdjustment
*) NULL
;
1775 m_oldHorizontalPos
= 0.0;
1776 m_oldVerticalPos
= 0.0;
1779 m_scrollGC
= (GdkGC
*) NULL
;
1780 m_widgetStyle
= (GtkStyle
*) NULL
;
1782 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1784 m_isStaticBox
= FALSE
;
1785 m_acceptsFocus
= FALSE
;
1788 wxWindow::wxWindow()
1793 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1794 const wxPoint
&pos
, const wxSize
&size
,
1795 long style
, const wxString
&name
)
1799 Create( parent
, id
, pos
, size
, style
, name
);
1802 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1803 const wxPoint
&pos
, const wxSize
&size
,
1804 long style
, const wxString
&name
)
1806 PreCreation( parent
, id
, pos
, size
, style
, name
);
1808 m_insertCallback
= wxInsertChildInWindow
;
1810 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1811 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1814 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1817 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1820 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1821 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1824 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1825 scroll_class
->scrollbar_spacing
= 0;
1827 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1829 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1830 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1832 m_wxwindow
= gtk_myfixed_new();
1835 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1838 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1840 #if (GTK_MINOR_VERSION > 0)
1841 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1843 if (HasFlag(wxRAISED_BORDER
))
1845 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1847 else if (HasFlag(wxSUNKEN_BORDER
))
1849 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1853 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1855 #else // GTK_MINOR_VERSION == 0
1856 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1858 if (HasFlag(wxRAISED_BORDER
))
1860 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1862 else if (HasFlag(wxSUNKEN_BORDER
))
1864 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1868 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1870 #endif // GTK_MINOR_VERSION
1872 if (HasFlag(wxTAB_TRAVERSAL
))
1874 /* we now allow a window to get the focus as long as it
1875 doesn't have any children. */
1876 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1877 m_acceptsFocus
= FALSE
;
1881 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1882 m_acceptsFocus
= TRUE
;
1885 #if (GTK_MINOR_VERSION == 0)
1886 // shut the viewport up
1887 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1888 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1889 #endif // GTK_MINOR_VERSION == 0
1891 // I _really_ don't want scrollbars in the beginning
1892 m_vAdjust
->lower
= 0.0;
1893 m_vAdjust
->upper
= 1.0;
1894 m_vAdjust
->value
= 0.0;
1895 m_vAdjust
->step_increment
= 1.0;
1896 m_vAdjust
->page_increment
= 1.0;
1897 m_vAdjust
->page_size
= 5.0;
1898 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1899 m_hAdjust
->lower
= 0.0;
1900 m_hAdjust
->upper
= 1.0;
1901 m_hAdjust
->value
= 0.0;
1902 m_hAdjust
->step_increment
= 1.0;
1903 m_hAdjust
->page_increment
= 1.0;
1904 m_hAdjust
->page_size
= 5.0;
1905 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1907 // these handlers block mouse events to any window during scrolling such as
1908 // motion events and prevent GTK and wxWindows from fighting over where the
1911 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1912 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1914 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1915 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1917 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1918 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1920 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1921 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1923 // these handlers get notified when screen updates are required either when
1924 // scrolling or when the window size (and therefore scrollbar configuration)
1927 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1928 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1929 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1930 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1932 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1933 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1934 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1935 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1937 gtk_widget_show( m_wxwindow
);
1940 m_parent
->DoAddChild( this );
1949 wxWindow::~wxWindow()
1951 m_isBeingDeleted
= TRUE
;
1960 m_parent
->RemoveChild( this );
1964 gtk_style_unref( m_widgetStyle
);
1965 m_widgetStyle
= (GtkStyle
*) NULL
;
1970 gdk_gc_unref( m_scrollGC
);
1971 m_scrollGC
= (GdkGC
*) NULL
;
1976 gtk_widget_destroy( m_wxwindow
);
1977 m_wxwindow
= (GtkWidget
*) NULL
;
1982 gtk_widget_destroy( m_widget
);
1983 m_widget
= (GtkWidget
*) NULL
;
1987 void wxWindow::PreCreation( wxWindow
*parent
,
1992 const wxString
&name
)
1994 wxASSERT_MSG( !m_needParent
|| parent
, _T("Need complete parent.") );
1996 if ( !CreateBase(parent
, id
, pos
, size
, style
, name
) )
1998 wxFAIL_MSG(_T("window creation failed"));
2001 m_width
= WidthDefault(size
.x
);
2002 m_height
= HeightDefault(size
.y
);
2007 if (!parent
) /* some reasonable defaults */
2011 m_x
= (gdk_screen_width () - m_width
) / 2;
2012 if (m_x
< 10) m_x
= 10;
2016 m_y
= (gdk_screen_height () - m_height
) / 2;
2017 if (m_y
< 10) m_y
= 10;
2022 void wxWindow::PostCreation()
2024 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2028 /* these get reported to wxWindows -> wxPaintEvent */
2029 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
2030 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
2032 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
2033 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
2035 #if (GTK_MINOR_VERSION > 0)
2036 /* these are called when the "sunken" or "raised" borders are drawn */
2037 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
2038 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
2040 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
2041 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
2045 GtkWidget
*connect_widget
= GetConnectWidget();
2047 ConnectWidget( connect_widget
);
2049 /* we cannot set colours, fonts and cursors before the widget has
2050 been realized, so we do this directly after realization */
2051 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
2052 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
2057 void wxWindow::ConnectWidget( GtkWidget
*widget
)
2059 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
2060 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
2062 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
2063 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
2065 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
2066 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
2068 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
2069 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
2071 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
2072 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
2074 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
2075 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2077 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
2078 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2080 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
2081 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
2083 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
2084 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
2087 bool wxWindow::Destroy()
2089 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2093 return wxWindowBase::Destroy();
2096 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
2098 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2099 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
2101 if (m_resizing
) return; /* I don't like recursions */
2104 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
2106 /* don't set the size for children of wxNotebook, just take the values. */
2114 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
2116 if (x
!= -1) m_x
= x
;
2117 if (y
!= -1) m_y
= y
;
2118 if (width
!= -1) m_width
= width
;
2119 if (height
!= -1) m_height
= height
;
2129 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2131 if (width
== -1) m_width
= 80;
2134 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2136 if (height
== -1) m_height
= 26;
2139 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2140 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2141 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2142 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2145 int bottom_border
= 0;
2147 if (GTK_WIDGET_CAN_DEFAULT(m_widget
))
2149 /* the default button has a border around it */
2154 /* this is the result of hours of debugging: the following code
2155 means that if we have a m_wxwindow and we set the size of
2156 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
2157 automatically propagate its size down to its m_wxwindow,
2158 which is its client area. therefore, we have to tell the
2159 client area directly that it has to resize itself.
2160 this will lead to that m_widget (GtkScrolledWindow) will
2161 calculate how much size it needs for scrollbars etc and
2162 it will then call XXX_size_allocate of its child, which
2163 is m_wxwindow. m_wxwindow in turn will do the same with its
2164 children and so on. problems can arise if this happens
2165 before all the children have been realized as some widgets
2166 stupidy need to be realized during XXX_size_allocate (e.g.
2167 GtkNotebook) and they will segv if called otherwise. this
2168 emergency is tested in gtk_myfixed_size_allocate. Normally
2169 this shouldn't be needed and only gtk_widget_queue_resize()
2170 should be enough to provoke a resize at the next appropriate
2171 moment, but this seems to fail, e.g. when a wxNotebook contains
2172 a wxSplitterWindow: the splitter window's children won't
2173 show up properly resized then. */
2175 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
2180 m_height
+border
+bottom_border
);
2185 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2186 event
.SetEventObject( this );
2187 GetEventHandler()->ProcessEvent( event
);
2192 void wxWindow::OnInternalIdle()
2194 GdkWindow
*window
= GetConnectWidget()->window
;
2197 wxCursor cursor
= m_cursor
;
2198 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2200 if (cursor
.Ok() && m_currentGdkCursor
!= cursor
)
2202 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2203 m_currentGdkCursor
= cursor
;
2210 void wxWindow::DoGetSize( int *width
, int *height
) const
2212 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2214 if (width
) (*width
) = m_width
;
2215 if (height
) (*height
) = m_height
;
2218 void wxWindow::DoSetClientSize( int width
, int height
)
2220 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2224 SetSize( width
, height
);
2231 if (!m_hasScrolling
)
2233 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2235 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2237 dw
+= 2 * window_class
->xthickness
;
2238 dh
+= 2 * window_class
->ythickness
;
2243 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2244 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2246 #if (GTK_MINOR_VERSION == 0)
2247 GtkWidget
*viewport
= scroll_window
->viewport
;
2248 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2250 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2252 dw
+= 2 * viewport_class
->xthickness
;
2253 dh
+= 2 * viewport_class
->ythickness
;
2258 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2259 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2261 we use this instead: range.slider_width = 11 + 2*2pts edge
2264 if (scroll_window
->vscrollbar_visible
)
2266 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2267 dw
+= scroll_class
->scrollbar_spacing
;
2270 if (scroll_window
->hscrollbar_visible
)
2272 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2273 dh
+= scroll_class
->scrollbar_spacing
;
2277 SetSize( width
+dw
, height
+dh
);
2281 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2283 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2287 if (width
) (*width
) = m_width
;
2288 if (height
) (*height
) = m_height
;
2295 if (!m_hasScrolling
)
2297 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2299 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2301 dw
+= 2 * window_class
->xthickness
;
2302 dh
+= 2 * window_class
->ythickness
;
2307 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2308 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2310 #if (GTK_MINOR_VERSION == 0)
2311 GtkWidget
*viewport
= scroll_window
->viewport
;
2312 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2314 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) )
2316 dw
+= 2 * viewport_class
->xthickness
;
2317 dh
+= 2 * viewport_class
->ythickness
;
2321 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2322 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2324 we use this instead: range.slider_width = 11 + 2*2pts edge
2327 if (scroll_window
->vscrollbar_visible
)
2329 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2330 dw
+= scroll_class
->scrollbar_spacing
;
2333 if (scroll_window
->hscrollbar_visible
)
2335 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2336 dh
+= scroll_class
->scrollbar_spacing
;
2340 if (width
) (*width
) = m_width
- dw
;
2341 if (height
) (*height
) = m_height
- dh
;
2345 void wxWindow::DoGetPosition( int *x
, int *y
) const
2347 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2353 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2355 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2357 if (!m_widget
->window
) return;
2359 GdkWindow
*source
= (GdkWindow
*) NULL
;
2361 source
= m_wxwindow
->window
;
2363 source
= m_widget
->window
;
2367 gdk_window_get_origin( source
, &org_x
, &org_y
);
2371 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2373 org_x
+= m_widget
->allocation
.x
;
2374 org_y
+= m_widget
->allocation
.y
;
2382 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2384 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2386 if (!m_widget
->window
) return;
2388 GdkWindow
*source
= (GdkWindow
*) NULL
;
2390 source
= m_wxwindow
->window
;
2392 source
= m_widget
->window
;
2396 gdk_window_get_origin( source
, &org_x
, &org_y
);
2400 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2402 org_x
+= m_widget
->allocation
.x
;
2403 org_y
+= m_widget
->allocation
.y
;
2411 bool wxWindow::Show( bool show
)
2413 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2415 if (!wxWindowBase::Show(show
))
2422 gtk_widget_show( m_widget
);
2424 gtk_widget_hide( m_widget
);
2429 bool wxWindow::Enable( bool enable
)
2431 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2433 if (!wxWindowBase::Enable(enable
))
2439 gtk_widget_set_sensitive( m_widget
, enable
);
2441 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2446 int wxWindow::GetCharHeight() const
2448 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2450 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2452 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2454 return font
->ascent
+ font
->descent
;
2457 int wxWindow::GetCharWidth() const
2459 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2461 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2463 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2465 return gdk_string_width( font
, "H" );
2468 void wxWindow::GetTextExtent( const wxString
& string
,
2472 int *externalLeading
,
2473 const wxFont
*theFont
) const
2475 wxFont fontToUse
= m_font
;
2476 if (theFont
) fontToUse
= *theFont
;
2478 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2480 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2481 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2482 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2483 if (descent
) (*descent
) = font
->descent
;
2484 if (externalLeading
) (*externalLeading
) = 0; // ??
2487 void wxWindow::SetFocus()
2489 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2491 GtkWidget
*connect_widget
= GetConnectWidget();
2494 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2496 gtk_widget_grab_focus (connect_widget
);
2498 else if (GTK_IS_CONTAINER(connect_widget
))
2500 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2508 bool wxWindow::AcceptsFocus() const
2510 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2513 bool wxWindow::Reparent( wxWindow
*newParent
)
2515 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2517 wxWindow
*oldParent
= m_parent
;
2519 if ( !wxWindowBase::Reparent(newParent
) )
2524 gtk_container_remove( GTK_CONTAINER(oldParent
->m_wxwindow
), m_widget
);
2529 /* insert GTK representation */
2530 (*(newParent
->m_insertCallback
))(newParent
, this);
2536 void wxWindow::DoAddChild(wxWindow
*child
)
2538 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2540 wxASSERT_MSG( (child
!= NULL
), _T("invalid child window") );
2542 wxASSERT_MSG( (m_insertCallback
!= NULL
), _T("invalid child insertion function") );
2547 /* insert GTK representation */
2548 (*m_insertCallback
)(this, child
);
2551 void wxWindow::Raise()
2553 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2555 if (!m_widget
->window
) return;
2557 gdk_window_raise( m_widget
->window
);
2560 void wxWindow::Lower()
2562 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2564 if (!m_widget
->window
) return;
2566 gdk_window_lower( m_widget
->window
);
2569 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2571 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2573 if (!wxWindowBase::SetCursor(cursor
))
2575 // don't leave if the GTK widget has just
2577 if (!m_delayedCursor
) return FALSE
;
2580 GtkWidget
*connect_widget
= GetConnectWidget();
2581 if (!connect_widget
->window
)
2583 // indicate that a new style has been set
2584 // but it couldn't get applied as the
2585 // widget hasn't been realized yet.
2586 m_delayedCursor
= TRUE
;
2588 // pretend we have done something
2592 // gdk_window_set_cursor( connect_widget->window, GetCursor().GetCursor() );
2598 void wxWindow::WarpPointer( int x
, int y
)
2600 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2602 GtkWidget
*connect_widget
= GetConnectWidget();
2603 if (connect_widget
->window
)
2605 /* we provide this function ourselves as it is
2607 gdk_window_warp_pointer( connect_widget
->window
, x
, y
);
2611 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2613 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2615 if (!m_widget
->window
) return;
2617 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2621 gdk_window_clear_area( m_wxwindow
->window
,
2623 rect
->width
, rect
->height
);
2627 gdk_window_clear( m_wxwindow
->window
);
2634 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2636 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2640 GdkRectangle gdk_rect
;
2641 gdk_rect
.x
= rect
->x
;
2642 gdk_rect
.y
= rect
->y
;
2643 gdk_rect
.width
= rect
->width
;
2644 gdk_rect
.height
= rect
->height
;
2647 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2649 gtk_widget_draw( m_widget
, &gdk_rect
);
2653 void wxWindow::Clear()
2655 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2657 if (!m_widget
->window
) return;
2659 if (m_wxwindow
&& m_wxwindow
->window
)
2661 gdk_window_clear( m_wxwindow
->window
);
2666 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2668 wxWindowBase::DoSetToolTip(tip
);
2671 m_tooltip
->Apply( this );
2674 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2676 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2678 #endif // wxUSE_TOOLTIPS
2680 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2682 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2684 if (!wxWindowBase::SetBackgroundColour(colour
))
2686 // don't leave if the GTK widget has just
2688 if (!m_delayedBackgroundColour
) return FALSE
;
2691 GtkWidget
*connect_widget
= GetConnectWidget();
2692 if (!connect_widget
->window
)
2694 // indicate that a new style has been set
2695 // but it couldn't get applied as the
2696 // widget hasn't been realized yet.
2697 m_delayedBackgroundColour
= TRUE
;
2699 // pretend we have done something
2703 if (m_wxwindow
&& m_wxwindow
->window
)
2705 /* wxMSW doesn't clear the window here. I don't do that either to
2706 provide compatibility. call Clear() to do the job. */
2708 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2709 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2712 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2713 if (sysbg
== m_backgroundColour
)
2715 m_backgroundColour
= wxNullColour
;
2717 m_backgroundColour
= sysbg
;
2727 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2729 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2731 if (!wxWindowBase::SetForegroundColour(colour
))
2733 // don't leave if the GTK widget has just
2735 if (!m_delayedForegroundColour
) return FALSE
;
2738 GtkWidget
*connect_widget
= GetConnectWidget();
2739 if (!connect_widget
->window
)
2741 // indicate that a new style has been set
2742 // but it couldn't get applied as the
2743 // widget hasn't been realized yet.
2744 m_delayedForegroundColour
= TRUE
;
2746 // pretend we have done something
2750 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2751 if ( sysbg
== m_backgroundColour
)
2753 m_backgroundColour
= wxNullColour
;
2755 m_backgroundColour
= sysbg
;
2765 GtkStyle
*wxWindow::GetWidgetStyle()
2767 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2769 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2771 return m_widgetStyle
;
2774 void wxWindow::SetWidgetStyle()
2776 GtkStyle
*style
= GetWidgetStyle();
2778 gdk_font_unref( style
->font
);
2779 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2781 if (m_foregroundColour
.Ok())
2783 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2784 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2785 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2786 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2789 if (m_backgroundColour
.Ok())
2791 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2792 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2793 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2794 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2795 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2796 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2797 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2798 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2799 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2803 void wxWindow::ApplyWidgetStyle()
2807 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2809 menu
->SetInvokingWindow( win
);
2810 wxNode
*node
= menu
->GetItems().First();
2813 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2814 if (menuitem
->IsSubMenu())
2816 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2818 node
= node
->Next();
2822 static gint gs_pop_x
= 0;
2823 static gint gs_pop_y
= 0;
2825 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2829 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2834 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2836 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2838 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2840 SetInvokingWindow( menu
, this );
2848 GTK_MENU(menu
->m_menu
),
2849 (GtkWidget
*) NULL
, // parent menu shell
2850 (GtkWidget
*) NULL
, // parent menu item
2851 (GtkMenuPositionFunc
) pop_pos_callback
,
2852 (gpointer
) this, // client data
2853 0, // button used to activate it
2854 0 //gs_timeLastClick // the time of activation
2859 #if wxUSE_DRAG_AND_DROP
2861 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2863 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2865 GtkWidget
*dnd_widget
= GetConnectWidget();
2867 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2869 if (m_dropTarget
) delete m_dropTarget
;
2870 m_dropTarget
= dropTarget
;
2872 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2875 #endif // wxUSE_DRAG_AND_DROP
2877 GtkWidget
* wxWindow::GetConnectWidget()
2879 GtkWidget
*connect_widget
= m_widget
;
2880 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2882 return connect_widget
;
2885 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2887 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2888 return (window
== m_widget
->window
);
2891 bool wxWindow::SetFont( const wxFont
&font
)
2893 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T( "invalid window") );
2895 if (!wxWindowBase::SetFont(font
))
2897 // don't leave if the GTK widget has just
2899 if (!m_delayedFont
) return FALSE
;
2902 GtkWidget
*connect_widget
= GetConnectWidget();
2903 if (!connect_widget
->window
)
2905 // indicate that a new style has been set
2906 // but it couldn't get applied as the
2907 // widget hasn't been realized yet.
2908 m_delayedFont
= TRUE
;
2910 // pretend we have done something
2914 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2915 if ( sysbg
== m_backgroundColour
)
2917 m_backgroundColour
= wxNullColour
;
2919 m_backgroundColour
= sysbg
;
2929 void wxWindow::CaptureMouse()
2931 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2933 wxCHECK_RET( g_captureWindow
== NULL
, _T("CaptureMouse called twice") );
2935 GtkWidget
*connect_widget
= GetConnectWidget();
2936 if (!connect_widget
->window
) return;
2938 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2940 (GDK_BUTTON_PRESS_MASK
|
2941 GDK_BUTTON_RELEASE_MASK
|
2942 GDK_POINTER_MOTION_MASK
),
2944 m_cursor
.GetCursor(),
2946 g_captureWindow
= this;
2949 void wxWindow::ReleaseMouse()
2951 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2953 wxCHECK_RET( g_captureWindow
, _T("ReleaseMouse called twice") );
2955 GtkWidget
*connect_widget
= GetConnectWidget();
2956 if (!connect_widget
->window
) return;
2958 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2959 g_captureWindow
= (wxWindow
*) NULL
;
2962 bool wxWindow::IsRetained() const
2967 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2968 int range
, bool refresh
)
2970 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2972 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2974 m_hasScrolling
= TRUE
;
2976 if (orient
== wxHORIZONTAL
)
2978 float fpos
= (float)pos
;
2979 float frange
= (float)range
;
2980 float fthumb
= (float)thumbVisible
;
2981 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2982 if (fpos
< 0.0) fpos
= 0.0;
2984 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2985 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2987 SetScrollPos( orient
, pos
, refresh
);
2991 m_oldHorizontalPos
= fpos
;
2993 m_hAdjust
->lower
= 0.0;
2994 m_hAdjust
->upper
= frange
;
2995 m_hAdjust
->value
= fpos
;
2996 m_hAdjust
->step_increment
= 1.0;
2997 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2998 m_hAdjust
->page_size
= fthumb
;
3002 float fpos
= (float)pos
;
3003 float frange
= (float)range
;
3004 float fthumb
= (float)thumbVisible
;
3005 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3006 if (fpos
< 0.0) fpos
= 0.0;
3008 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3009 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3011 SetScrollPos( orient
, pos
, refresh
);
3015 m_oldVerticalPos
= fpos
;
3017 m_vAdjust
->lower
= 0.0;
3018 m_vAdjust
->upper
= frange
;
3019 m_vAdjust
->value
= fpos
;
3020 m_vAdjust
->step_increment
= 1.0;
3021 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3022 m_vAdjust
->page_size
= fthumb
;
3025 if (orient
== wxHORIZONTAL
)
3026 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3028 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3031 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3033 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3035 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3037 if (orient
== wxHORIZONTAL
)
3039 float fpos
= (float)pos
;
3040 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3041 if (fpos
< 0.0) fpos
= 0.0;
3042 m_oldHorizontalPos
= fpos
;
3044 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3045 m_hAdjust
->value
= fpos
;
3049 float fpos
= (float)pos
;
3050 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3051 if (fpos
< 0.0) fpos
= 0.0;
3052 m_oldVerticalPos
= fpos
;
3054 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3055 m_vAdjust
->value
= fpos
;
3058 if (!m_isScrolling
) /* prevent recursion */
3060 if (m_wxwindow
->window
)
3062 if (orient
== wxHORIZONTAL
)
3063 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3065 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3070 int wxWindow::GetScrollThumb( int orient
) const
3072 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3074 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3076 if (orient
== wxHORIZONTAL
)
3077 return (int)(m_hAdjust
->page_size
+0.5);
3079 return (int)(m_vAdjust
->page_size
+0.5);
3082 int wxWindow::GetScrollPos( int orient
) const
3084 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3086 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3088 if (orient
== wxHORIZONTAL
)
3089 return (int)(m_hAdjust
->value
+0.5);
3091 return (int)(m_vAdjust
->value
+0.5);
3094 int wxWindow::GetScrollRange( int orient
) const
3096 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3098 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3100 if (orient
== wxHORIZONTAL
)
3101 return (int)(m_hAdjust
->upper
+0.5);
3103 return (int)(m_vAdjust
->upper
+0.5);
3106 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3108 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3110 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3114 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3115 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3118 wxNode
*node
= m_children
.First();
3121 wxWindow
*child
= (wxWindow
*) node
->Data();
3124 child
->GetSize( &sx
, &sy
);
3125 child
->SetSize( child
->m_x
+ dx
, child
->m_y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
3126 node
= node
->Next();
3131 GetClientSize( &cw
, &ch
);
3132 int w
= cw
- abs(dx
);
3133 int h
= ch
- abs(dy
);
3135 if ((h
< 0) || (w
< 0))
3143 if (dx
< 0) s_x
= -dx
;
3144 if (dy
< 0) s_y
= -dy
;
3147 if (dx
> 0) d_x
= dx
;
3148 if (dy
> 0) d_y
= dy
;
3150 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3151 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3154 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3155 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3156 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3157 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3159 Refresh( TRUE
, &rect
);
3163 void wxWindow::SetScrolling(bool scroll
)
3165 m_isScrolling
= g_blockEventsOnScroll
= scroll
;