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
)
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
));
816 /* win is a control: tab can be propagated up */
818 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
819 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
821 wxNavigationKeyEvent new_event
;
822 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
823 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
824 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
825 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
826 new_event
.SetCurrentFocus( win
);
827 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
830 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
832 (gdk_event
->keyval
== GDK_Escape
) )
834 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
835 new_event
.SetEventObject( win
);
836 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
839 #if (GTK_MINOR_VERSION > 0)
840 /* pressing F10 will activate the menu bar of the top frame */
842 (gdk_event
->keyval
== GDK_F10
) )
844 wxWindow
*ancestor
= win
;
847 if (wxIsKindOf(ancestor
,wxFrame
))
849 wxFrame
*frame
= (wxFrame
*) ancestor
;
850 wxMenuBar
*menubar
= frame
->GetMenuBar();
853 wxNode
*node
= menubar
->GetMenus().First();
856 // doesn't work correctly
857 // wxMenu *firstMenu = (wxMenu*) node->Data();
858 // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
864 ancestor
= ancestor
->GetParent();
870 Damn, I forgot why this didn't work, but it didn't work.
872 // win is a panel: up can be propagated to the panel
873 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
874 (gdk_event->keyval == GDK_Up))
876 win->m_parent->SetFocus();
880 // win is a panel: left/right can be propagated to the panel
881 if ((!ret) && (win->m_wxwindow) &&
882 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
883 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
885 wxNavigationKeyEvent new_event;
886 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
887 new_event.SetCurrentFocus( win );
888 ret = win->GetEventHandler()->ProcessEvent( new_event );
894 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
901 //-----------------------------------------------------------------------------
902 // "key_release_event" from any window
903 //-----------------------------------------------------------------------------
905 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
908 wxapp_install_idle_handler();
910 if (!win
->m_hasVMT
) return FALSE
;
911 if (g_blockEventsOnDrag
) return FALSE
;
914 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
915 if (gdk_event->state & GDK_SHIFT_MASK)
916 printf( "ShiftDown.\n" );
918 printf( "ShiftUp.\n" );
919 if (gdk_event->state & GDK_CONTROL_MASK)
920 printf( "ControlDown.\n" );
922 printf( "ControlUp.\n" );
926 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
928 /* sending unknown key events doesn't really make sense */
929 if (key_code
== 0) return FALSE
;
933 GdkModifierType state
;
934 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
936 wxKeyEvent
event( wxEVT_KEY_UP
);
937 event
.SetTimestamp( gdk_event
->time
);
938 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
939 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
940 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
941 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
942 event
.m_keyCode
= key_code
;
943 event
.m_scanCode
= gdk_event
->keyval
;
946 event
.SetEventObject( win
);
948 if (win
->GetEventHandler()->ProcessEvent( event
))
950 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
957 //-----------------------------------------------------------------------------
958 // "button_press_event"
959 //-----------------------------------------------------------------------------
961 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
964 wxapp_install_idle_handler();
967 wxPrintf( _T("1) OnButtonPress from ") );
968 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
969 wxPrintf( win->GetClassInfo()->GetClassName() );
970 wxPrintf( _T(".\n") );
972 if (!win
->m_hasVMT
) return FALSE
;
973 if (g_blockEventsOnDrag
) return TRUE
;
974 if (g_blockEventsOnScroll
) return TRUE
;
976 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
980 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
982 gtk_widget_grab_focus (win
->m_wxwindow
);
985 wxPrintf( _T("GrabFocus from ") );
986 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
987 wxPrintf( win->GetClassInfo()->GetClassName() );
988 wxPrintf( _T(".\n") );
995 wxPrintf( _T("2) OnButtonPress from ") );
996 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
997 wxPrintf( win->GetClassInfo()->GetClassName() );
998 wxPrintf( _T(".\n") );
1001 wxEventType event_type
= wxEVT_LEFT_DOWN
;
1003 if (gdk_event
->button
== 1)
1005 switch (gdk_event
->type
)
1007 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
1008 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
1012 else if (gdk_event
->button
== 2)
1014 switch (gdk_event
->type
)
1016 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
1017 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
1021 else if (gdk_event
->button
== 3)
1023 switch (gdk_event
->type
)
1025 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
1026 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
1031 wxMouseEvent
event( event_type
);
1032 event
.SetTimestamp( gdk_event
->time
);
1033 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1034 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1035 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1036 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1037 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1038 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1039 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1041 event
.m_x
= (long)gdk_event
->x
;
1042 event
.m_y
= (long)gdk_event
->y
;
1044 // Some control don't have their own X window and thus cannot get
1047 if (!g_captureWindow
)
1049 wxNode
*node
= win
->GetChildren().First();
1052 wxWindow
*child
= (wxWindow
*)node
->Data();
1054 if (child
->m_isStaticBox
)
1056 // wxStaticBox is transparent in the box itself
1059 int xx1
= child
->m_x
;
1060 int yy1
= child
->m_y
;
1061 int xx2
= child
->m_x
+ child
->m_width
;
1062 int yy2
= child
->m_x
+ child
->m_height
;
1065 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1067 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1069 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1071 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1074 event
.m_x
-= child
->m_x
;
1075 event
.m_y
-= child
->m_y
;
1082 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1083 (child
->m_x
<= event
.m_x
) &&
1084 (child
->m_y
<= event
.m_y
) &&
1085 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1086 (child
->m_y
+child
->m_height
>= event
.m_y
))
1089 event
.m_x
-= child
->m_x
;
1090 event
.m_y
-= child
->m_y
;
1094 node
= node
->Next();
1098 event
.SetEventObject( win
);
1100 gs_timeLastClick
= gdk_event
->time
;
1102 if (win
->GetEventHandler()->ProcessEvent( event
))
1104 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
1111 //-----------------------------------------------------------------------------
1112 // "button_release_event"
1113 //-----------------------------------------------------------------------------
1115 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1118 wxapp_install_idle_handler();
1120 if (!win
->m_hasVMT
) return FALSE
;
1121 if (g_blockEventsOnDrag
) return FALSE
;
1122 if (g_blockEventsOnScroll
) return FALSE
;
1124 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1127 printf( "OnButtonRelease from " );
1128 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1129 printf( win->GetClassInfo()->GetClassName() );
1133 wxEventType event_type
= wxEVT_NULL
;
1135 switch (gdk_event
->button
)
1137 case 1: event_type
= wxEVT_LEFT_UP
; break;
1138 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
1139 case 3: event_type
= wxEVT_RIGHT_UP
; break;
1142 wxMouseEvent
event( event_type
);
1143 event
.SetTimestamp( gdk_event
->time
);
1144 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1145 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1146 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1147 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1148 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1149 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1150 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1151 event
.m_x
= (long)gdk_event
->x
;
1152 event
.m_y
= (long)gdk_event
->y
;
1154 // Some control don't have their own X window and thus cannot get
1157 if (!g_captureWindow
)
1159 wxNode
*node
= win
->GetChildren().First();
1162 wxWindow
*child
= (wxWindow
*)node
->Data();
1164 if (child
->m_isStaticBox
)
1166 // wxStaticBox is transparent in the box itself
1169 int xx1
= child
->m_x
;
1170 int yy1
= child
->m_y
;
1171 int xx2
= child
->m_x
+ child
->m_width
;
1172 int yy2
= child
->m_x
+ child
->m_height
;
1175 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1177 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1179 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1181 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1184 event
.m_x
-= child
->m_x
;
1185 event
.m_y
-= child
->m_y
;
1192 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1193 (child
->m_x
<= event
.m_x
) &&
1194 (child
->m_y
<= event
.m_y
) &&
1195 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1196 (child
->m_y
+child
->m_height
>= event
.m_y
))
1199 event
.m_x
-= child
->m_x
;
1200 event
.m_y
-= child
->m_y
;
1204 node
= node
->Next();
1208 event
.SetEventObject( win
);
1210 if (win
->GetEventHandler()->ProcessEvent( event
))
1212 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1219 //-----------------------------------------------------------------------------
1220 // "motion_notify_event"
1221 //-----------------------------------------------------------------------------
1223 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1226 wxapp_install_idle_handler();
1228 if (!win
->m_hasVMT
) return FALSE
;
1229 if (g_blockEventsOnDrag
) return FALSE
;
1230 if (g_blockEventsOnScroll
) return FALSE
;
1232 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1234 if (gdk_event
->is_hint
)
1238 GdkModifierType state
;
1239 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1242 gdk_event
->state
= state
;
1246 printf( "OnMotion from " );
1247 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1248 printf( win->GetClassInfo()->GetClassName() );
1252 wxMouseEvent
event( wxEVT_MOTION
);
1253 event
.SetTimestamp( gdk_event
->time
);
1254 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1255 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1256 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1257 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1258 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1259 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1260 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1262 event
.m_x
= (long)gdk_event
->x
;
1263 event
.m_y
= (long)gdk_event
->y
;
1265 // Some control don't have their own X window and thus cannot get
1268 if (!g_captureWindow
)
1270 wxNode
*node
= win
->GetChildren().First();
1273 wxWindow
*child
= (wxWindow
*)node
->Data();
1275 if (child
->m_isStaticBox
)
1277 // wxStaticBox is transparent in the box itself
1280 int xx1
= child
->m_x
;
1281 int yy1
= child
->m_y
;
1282 int xx2
= child
->m_x
+ child
->m_width
;
1283 int yy2
= child
->m_x
+ child
->m_height
;
1286 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1288 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1290 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1292 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1295 event
.m_x
-= child
->m_x
;
1296 event
.m_y
-= child
->m_y
;
1303 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1304 (child
->m_x
<= event
.m_x
) &&
1305 (child
->m_y
<= event
.m_y
) &&
1306 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1307 (child
->m_y
+child
->m_height
>= event
.m_y
))
1310 event
.m_x
-= child
->m_x
;
1311 event
.m_y
-= child
->m_y
;
1315 node
= node
->Next();
1319 event
.SetEventObject( win
);
1321 if (win
->GetEventHandler()->ProcessEvent( event
))
1323 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1330 //-----------------------------------------------------------------------------
1332 //-----------------------------------------------------------------------------
1334 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1337 wxapp_install_idle_handler();
1339 if (!win
->m_hasVMT
) return FALSE
;
1340 if (g_blockEventsOnDrag
) return FALSE
;
1342 g_focusWindow
= win
;
1344 if (win
->m_wxwindow
)
1346 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1348 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1350 printf( "SetFocus flag from " );
1351 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1352 printf( win->GetClassInfo()->GetClassName() );
1360 printf( "OnSetFocus from " );
1361 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1362 printf( win->GetClassInfo()->GetClassName() );
1364 printf( WXSTRINGCAST win->GetLabel() );
1368 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1369 event
.SetEventObject( win
);
1371 if (win
->GetEventHandler()->ProcessEvent( event
))
1373 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1380 //-----------------------------------------------------------------------------
1381 // "focus_out_event"
1382 //-----------------------------------------------------------------------------
1384 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1387 wxapp_install_idle_handler();
1389 if (!win
->m_hasVMT
) return FALSE
;
1390 if (g_blockEventsOnDrag
) return FALSE
;
1392 if (win
->m_wxwindow
)
1394 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1395 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1399 printf( "OnKillFocus from " );
1400 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1401 printf( win->GetClassInfo()->GetClassName() );
1405 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1406 event
.SetEventObject( win
);
1408 if (win
->GetEventHandler()->ProcessEvent( event
))
1410 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1417 //-----------------------------------------------------------------------------
1418 // "enter_notify_event"
1419 //-----------------------------------------------------------------------------
1421 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1424 wxapp_install_idle_handler();
1426 if (!win
->m_hasVMT
) return FALSE
;
1427 if (g_blockEventsOnDrag
) return FALSE
;
1429 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1431 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1432 #if (GTK_MINOR_VERSION > 0)
1433 event
.SetTimestamp( gdk_event
->time
);
1435 event
.SetEventObject( win
);
1439 GdkModifierType state
= (GdkModifierType
)0;
1441 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1443 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1444 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1445 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1446 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1447 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1448 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1449 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1451 event
.m_x
= (long)x
;
1452 event
.m_y
= (long)y
;
1454 if (win
->GetEventHandler()->ProcessEvent( event
))
1456 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1463 //-----------------------------------------------------------------------------
1464 // "leave_notify_event"
1465 //-----------------------------------------------------------------------------
1467 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1470 wxapp_install_idle_handler();
1472 if (!win
->m_hasVMT
) return FALSE
;
1473 if (g_blockEventsOnDrag
) return FALSE
;
1475 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1477 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1478 #if (GTK_MINOR_VERSION > 0)
1479 event
.SetTimestamp( gdk_event
->time
);
1481 event
.SetEventObject( win
);
1485 GdkModifierType state
= (GdkModifierType
)0;
1487 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1489 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1490 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1491 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1492 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1493 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1494 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1495 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1497 event
.m_x
= (long)x
;
1498 event
.m_y
= (long)y
;
1500 if (win
->GetEventHandler()->ProcessEvent( event
))
1502 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1509 //-----------------------------------------------------------------------------
1510 // "value_changed" from m_vAdjust
1511 //-----------------------------------------------------------------------------
1513 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1516 wxapp_install_idle_handler();
1518 if (g_blockEventsOnDrag
) return;
1520 if (!win
->m_hasVMT
) return;
1522 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1523 if (fabs(diff
) < 0.2) return;
1524 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1526 wxEventType command
= wxEVT_NULL
;
1528 float line_step
= win
->m_vAdjust
->step_increment
;
1529 float page_step
= win
->m_vAdjust
->page_increment
;
1531 if (win
->IsScrolling())
1533 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1537 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1538 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1539 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1540 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1541 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1542 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1543 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1546 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1548 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1549 event
.SetEventObject( win
);
1550 win
->GetEventHandler()->ProcessEvent( event
);
1553 //-----------------------------------------------------------------------------
1554 // "value_changed" from m_hAdjust
1555 //-----------------------------------------------------------------------------
1557 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1560 wxapp_install_idle_handler();
1562 if (g_blockEventsOnDrag
) return;
1563 if (!win
->m_hasVMT
) return;
1565 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1566 if (fabs(diff
) < 0.2) return;
1567 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1569 wxEventType command
= wxEVT_NULL
;
1571 float line_step
= win
->m_hAdjust
->step_increment
;
1572 float page_step
= win
->m_hAdjust
->page_increment
;
1574 if (win
->IsScrolling())
1576 command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1580 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLLWIN_BOTTOM
;
1581 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLLWIN_TOP
;
1582 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1583 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLLWIN_LINEUP
;
1584 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1585 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLLWIN_PAGEUP
;
1586 else command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1589 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1591 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1592 event
.SetEventObject( win
);
1593 win
->GetEventHandler()->ProcessEvent( event
);
1596 //-----------------------------------------------------------------------------
1597 // "changed" from m_vAdjust
1598 //-----------------------------------------------------------------------------
1600 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1603 wxapp_install_idle_handler();
1605 if (g_blockEventsOnDrag
) return;
1606 if (!win
->m_hasVMT
) return;
1608 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1609 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1611 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1612 event
.SetEventObject( win
);
1613 win
->GetEventHandler()->ProcessEvent( event
);
1616 //-----------------------------------------------------------------------------
1617 // "changed" from m_hAdjust
1618 //-----------------------------------------------------------------------------
1620 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1623 wxapp_install_idle_handler();
1625 if (g_blockEventsOnDrag
) return;
1626 if (!win
->m_hasVMT
) return;
1628 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1629 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1631 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1632 event
.SetEventObject( win
);
1633 win
->GetEventHandler()->ProcessEvent( event
);
1636 //-----------------------------------------------------------------------------
1637 // "button_press_event" from scrollbar
1638 //-----------------------------------------------------------------------------
1640 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1641 GdkEventButton
*WXUNUSED(gdk_event
),
1645 wxapp_install_idle_handler();
1647 // don't test here as we can release the mouse while being over
1648 // a different window then the slider
1650 // if (gdk_event->window != widget->slider) return FALSE;
1652 win
->SetScrolling( TRUE
);
1657 //-----------------------------------------------------------------------------
1658 // "button_release_event" from scrollbar
1659 //-----------------------------------------------------------------------------
1661 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1662 GdkEventButton
*WXUNUSED(gdk_event
),
1666 // don't test here as we can release the mouse while being over
1667 // a different window then the slider
1669 // if (gdk_event->window != widget->slider) return FALSE;
1671 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1673 if (widget
== GTK_RANGE(scrolledWindow
->vscrollbar
))
1674 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1676 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1678 win
->SetScrolling( FALSE
);
1683 // ----------------------------------------------------------------------------
1684 // this wxWindowBase function is implemented here (in platform-specific file)
1685 // because it is static and so couldn't be made virtual
1686 // ----------------------------------------------------------------------------
1688 wxWindow
*wxWindowBase::FindFocus()
1690 return g_focusWindow
;
1693 //-----------------------------------------------------------------------------
1694 // "realize" from m_widget
1695 //-----------------------------------------------------------------------------
1697 /* we cannot set colours, fonts and cursors before the widget has
1698 been realized, so we do this directly after realization */
1701 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1704 wxapp_install_idle_handler();
1706 if (win
->m_delayedFont
)
1707 win
->SetFont( win
->GetFont() );
1709 if (win
->m_delayedBackgroundColour
)
1710 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1712 if (win
->m_delayedForegroundColour
)
1713 win
->SetForegroundColour( win
->GetForegroundColour() );
1715 win
->SetCursor( win
->GetCursor() );
1717 wxWindowCreateEvent
event( win
);
1718 event
.SetEventObject( win
);
1719 win
->GetEventHandler()->ProcessEvent( event
);
1724 //-----------------------------------------------------------------------------
1725 // InsertChild for wxWindow.
1726 //-----------------------------------------------------------------------------
1728 /* Callback for wxWindow. This very strange beast has to be used because
1729 * C++ has no virtual methods in a constructor. We have to emulate a
1730 * virtual function here as wxNotebook requires a different way to insert
1731 * a child in it. I had opted for creating a wxNotebookPage window class
1732 * which would have made this superfluous (such in the MDI window system),
1733 * but no-one was listening to me... */
1735 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1737 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1738 GTK_WIDGET(child
->m_widget
),
1744 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1746 /* we now allow a window to get the focus as long as it
1747 doesn't have any children. */
1748 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1752 //-----------------------------------------------------------------------------
1754 //-----------------------------------------------------------------------------
1756 wxWindow
* wxGetActiveWindow()
1758 return g_focusWindow
;
1761 //-----------------------------------------------------------------------------
1763 //-----------------------------------------------------------------------------
1765 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1767 void wxWindow::Init()
1773 m_widget
= (GtkWidget
*) NULL
;
1774 m_wxwindow
= (GtkWidget
*) NULL
;
1784 m_needParent
= TRUE
;
1785 m_isBeingDeleted
= FALSE
;
1787 m_hasScrolling
= FALSE
;
1788 m_isScrolling
= FALSE
;
1790 m_hAdjust
= (GtkAdjustment
*) NULL
;
1791 m_vAdjust
= (GtkAdjustment
*) NULL
;
1792 m_oldHorizontalPos
= 0.0;
1793 m_oldVerticalPos
= 0.0;
1796 m_scrollGC
= (GdkGC
*) NULL
;
1797 m_widgetStyle
= (GtkStyle
*) NULL
;
1799 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1801 m_isStaticBox
= FALSE
;
1802 m_isRadioButton
= FALSE
;
1803 m_acceptsFocus
= FALSE
;
1806 wxWindow::wxWindow()
1811 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1812 const wxPoint
&pos
, const wxSize
&size
,
1813 long style
, const wxString
&name
)
1817 Create( parent
, id
, pos
, size
, style
, name
);
1820 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1821 const wxPoint
&pos
, const wxSize
&size
,
1822 long style
, const wxString
&name
)
1824 if (!PreCreation( parent
, pos
, size
) ||
1825 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
1827 wxFAIL_MSG( _T("wxWindow creation failed") );
1831 m_insertCallback
= wxInsertChildInWindow
;
1833 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1834 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1837 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1840 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1843 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1844 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1847 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1848 scroll_class
->scrollbar_spacing
= 0;
1850 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1852 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1853 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1855 m_wxwindow
= gtk_myfixed_new();
1858 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1861 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1863 #if (GTK_MINOR_VERSION > 0)
1864 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1866 if (HasFlag(wxRAISED_BORDER
))
1868 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1870 else if (HasFlag(wxSUNKEN_BORDER
))
1872 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1876 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1878 #else // GTK_MINOR_VERSION == 0
1879 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1881 if (HasFlag(wxRAISED_BORDER
))
1883 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1885 else if (HasFlag(wxSUNKEN_BORDER
))
1887 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1891 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1893 #endif // GTK_MINOR_VERSION
1895 if (HasFlag(wxTAB_TRAVERSAL
))
1897 /* we now allow a window to get the focus as long as it
1898 doesn't have any children. */
1899 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1900 m_acceptsFocus
= FALSE
;
1904 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1905 m_acceptsFocus
= TRUE
;
1908 #if (GTK_MINOR_VERSION == 0)
1909 // shut the viewport up
1910 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1911 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1912 #endif // GTK_MINOR_VERSION == 0
1914 // I _really_ don't want scrollbars in the beginning
1915 m_vAdjust
->lower
= 0.0;
1916 m_vAdjust
->upper
= 1.0;
1917 m_vAdjust
->value
= 0.0;
1918 m_vAdjust
->step_increment
= 1.0;
1919 m_vAdjust
->page_increment
= 1.0;
1920 m_vAdjust
->page_size
= 5.0;
1921 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1922 m_hAdjust
->lower
= 0.0;
1923 m_hAdjust
->upper
= 1.0;
1924 m_hAdjust
->value
= 0.0;
1925 m_hAdjust
->step_increment
= 1.0;
1926 m_hAdjust
->page_increment
= 1.0;
1927 m_hAdjust
->page_size
= 5.0;
1928 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1930 // these handlers block mouse events to any window during scrolling such as
1931 // motion events and prevent GTK and wxWindows from fighting over where the
1934 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1935 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1937 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1938 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1940 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1941 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1943 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1944 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1946 // these handlers get notified when screen updates are required either when
1947 // scrolling or when the window size (and therefore scrollbar configuration)
1950 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1951 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1952 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1953 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1955 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1956 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1957 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1958 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1960 gtk_widget_show( m_wxwindow
);
1963 m_parent
->DoAddChild( this );
1972 wxWindow::~wxWindow()
1974 m_isBeingDeleted
= TRUE
;
1983 m_parent
->RemoveChild( this );
1987 gtk_style_unref( m_widgetStyle
);
1988 m_widgetStyle
= (GtkStyle
*) NULL
;
1993 gdk_gc_unref( m_scrollGC
);
1994 m_scrollGC
= (GdkGC
*) NULL
;
1999 gtk_widget_destroy( m_wxwindow
);
2000 m_wxwindow
= (GtkWidget
*) NULL
;
2005 gtk_widget_destroy( m_widget
);
2006 m_widget
= (GtkWidget
*) NULL
;
2010 bool wxWindow::PreCreation( wxWindow
*parent
, const wxPoint
&pos
, const wxSize
&size
)
2012 wxCHECK_MSG( !m_needParent
|| parent
, FALSE
, _T("Need complete parent.") );
2014 /* this turns -1 into 20 so that a minimal window is
2015 visible even although -1,-1 has been given as the
2016 size of the window. the same trick is used in other
2017 ports and should make debugging easier */
2018 m_width
= WidthDefault(size
.x
);
2019 m_height
= HeightDefault(size
.y
);
2024 /* some reasonable defaults */
2029 m_x
= (gdk_screen_width () - m_width
) / 2;
2030 if (m_x
< 10) m_x
= 10;
2034 m_y
= (gdk_screen_height () - m_height
) / 2;
2035 if (m_y
< 10) m_y
= 10;
2042 void wxWindow::PostCreation()
2044 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2048 /* these get reported to wxWindows -> wxPaintEvent */
2049 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
2050 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
2052 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
2053 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
2055 #if (GTK_MINOR_VERSION > 0)
2056 /* these are called when the "sunken" or "raised" borders are drawn */
2057 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
2058 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
2060 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
2061 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
2065 GtkWidget
*connect_widget
= GetConnectWidget();
2067 ConnectWidget( connect_widget
);
2069 /* we cannot set colours, fonts and cursors before the widget has
2070 been realized, so we do this directly after realization */
2071 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
2072 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
2077 void wxWindow::ConnectWidget( GtkWidget
*widget
)
2079 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
2080 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
2082 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
2083 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
2085 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
2086 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
2088 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
2089 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
2091 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
2092 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
2094 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
2095 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2097 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
2098 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2100 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
2101 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
2103 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
2104 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
2107 bool wxWindow::Destroy()
2109 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2113 return wxWindowBase::Destroy();
2116 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
2118 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2119 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
2121 if (m_resizing
) return; /* I don't like recursions */
2124 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
2126 /* don't set the size for children of wxNotebook, just take the values. */
2134 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
2136 if (x
!= -1) m_x
= x
;
2137 if (y
!= -1) m_y
= y
;
2138 if (width
!= -1) m_width
= width
;
2139 if (height
!= -1) m_height
= height
;
2149 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2151 if (width
== -1) m_width
= 80;
2154 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2156 if (height
== -1) m_height
= 26;
2159 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2160 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2161 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2162 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2165 int bottom_border
= 0;
2167 if (GTK_WIDGET_CAN_DEFAULT(m_widget
))
2169 /* the default button has a border around it */
2174 /* this is the result of hours of debugging: the following code
2175 means that if we have a m_wxwindow and we set the size of
2176 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
2177 automatically propagate its size down to its m_wxwindow,
2178 which is its client area. therefore, we have to tell the
2179 client area directly that it has to resize itself.
2180 this will lead to that m_widget (GtkScrolledWindow) will
2181 calculate how much size it needs for scrollbars etc and
2182 it will then call XXX_size_allocate of its child, which
2183 is m_wxwindow. m_wxwindow in turn will do the same with its
2184 children and so on. problems can arise if this happens
2185 before all the children have been realized as some widgets
2186 stupidy need to be realized during XXX_size_allocate (e.g.
2187 GtkNotebook) and they will segv if called otherwise. this
2188 emergency is tested in gtk_myfixed_size_allocate. Normally
2189 this shouldn't be needed and only gtk_widget_queue_resize()
2190 should be enough to provoke a resize at the next appropriate
2191 moment, but this seems to fail, e.g. when a wxNotebook contains
2192 a wxSplitterWindow: the splitter window's children won't
2193 show up properly resized then. */
2195 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
2200 m_height
+border
+bottom_border
);
2205 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2206 event
.SetEventObject( this );
2207 GetEventHandler()->ProcessEvent( event
);
2212 void wxWindow::OnInternalIdle()
2214 wxCursor cursor
= m_cursor
;
2215 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2217 if (cursor
.Ok() && m_currentGdkCursor
!= cursor
)
2219 m_currentGdkCursor
= cursor
;
2223 GdkWindow
*window
= m_wxwindow
->window
;
2225 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2227 if (!g_globalCursor
.Ok())
2228 cursor
= *wxSTANDARD_CURSOR
;
2230 window
= m_widget
->window
;
2232 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2236 GdkWindow
*window
= m_widget
->window
;
2238 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2245 void wxWindow::DoGetSize( int *width
, int *height
) const
2247 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2249 if (width
) (*width
) = m_width
;
2250 if (height
) (*height
) = m_height
;
2253 void wxWindow::DoSetClientSize( int width
, int height
)
2255 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2259 SetSize( width
, height
);
2266 #if (GTK_MINOR_VERSION == 0)
2267 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2271 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2272 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2274 GtkWidget
*viewport
= scroll_window
->viewport
;
2275 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2277 dw
+= 2 * viewport_class
->xthickness
;
2278 dh
+= 2 * viewport_class
->ythickness
;
2282 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2284 /* when using GTK 1.2 we set the border size to 2 */
2293 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2294 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2296 we use this instead: range.slider_width = 11 + 2*2pts edge
2299 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2300 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2302 if (scroll_window
->vscrollbar_visible
)
2304 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2305 dw
+= scroll_class
->scrollbar_spacing
;
2308 if (scroll_window
->hscrollbar_visible
)
2310 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2311 dh
+= scroll_class
->scrollbar_spacing
;
2315 SetSize( width
+dw
, height
+dh
);
2319 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2321 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2325 if (width
) (*width
) = m_width
;
2326 if (height
) (*height
) = m_height
;
2333 #if (GTK_MINOR_VERSION == 0)
2334 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2338 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2339 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2341 GtkWidget
*viewport
= scroll_window
->viewport
;
2342 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2344 dw
+= 2 * viewport_class
->xthickness
;
2345 dh
+= 2 * viewport_class
->ythickness
;
2349 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2351 /* when using GTK 1.2 we set the border size to 2 */
2359 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2360 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2362 we use this instead: range.slider_width = 11 + 2*2pts edge
2365 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2366 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2368 if (scroll_window
->vscrollbar_visible
)
2370 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2371 dw
+= scroll_class
->scrollbar_spacing
;
2374 if (scroll_window
->hscrollbar_visible
)
2376 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2377 dh
+= scroll_class
->scrollbar_spacing
;
2381 if (width
) (*width
) = m_width
- dw
;
2382 if (height
) (*height
) = m_height
- dh
;
2386 void wxWindow::DoGetPosition( int *x
, int *y
) const
2388 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2394 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2396 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2398 if (!m_widget
->window
) return;
2400 GdkWindow
*source
= (GdkWindow
*) NULL
;
2402 source
= m_wxwindow
->window
;
2404 source
= m_widget
->window
;
2408 gdk_window_get_origin( source
, &org_x
, &org_y
);
2412 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2414 org_x
+= m_widget
->allocation
.x
;
2415 org_y
+= m_widget
->allocation
.y
;
2423 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2425 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2427 if (!m_widget
->window
) return;
2429 GdkWindow
*source
= (GdkWindow
*) NULL
;
2431 source
= m_wxwindow
->window
;
2433 source
= m_widget
->window
;
2437 gdk_window_get_origin( source
, &org_x
, &org_y
);
2441 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2443 org_x
+= m_widget
->allocation
.x
;
2444 org_y
+= m_widget
->allocation
.y
;
2452 bool wxWindow::Show( bool show
)
2454 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2456 if (!wxWindowBase::Show(show
))
2463 gtk_widget_show( m_widget
);
2465 gtk_widget_hide( m_widget
);
2470 bool wxWindow::Enable( bool enable
)
2472 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2474 if (!wxWindowBase::Enable(enable
))
2480 gtk_widget_set_sensitive( m_widget
, enable
);
2482 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2487 int wxWindow::GetCharHeight() const
2489 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2491 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2493 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2495 return font
->ascent
+ font
->descent
;
2498 int wxWindow::GetCharWidth() const
2500 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2502 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2504 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2506 return gdk_string_width( font
, "H" );
2509 void wxWindow::GetTextExtent( const wxString
& string
,
2513 int *externalLeading
,
2514 const wxFont
*theFont
) const
2516 wxFont fontToUse
= m_font
;
2517 if (theFont
) fontToUse
= *theFont
;
2519 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2521 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2522 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2523 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2524 if (descent
) (*descent
) = font
->descent
;
2525 if (externalLeading
) (*externalLeading
) = 0; // ??
2528 void wxWindow::SetFocus()
2530 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2532 GtkWidget
*connect_widget
= GetConnectWidget();
2535 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2537 gtk_widget_grab_focus (connect_widget
);
2539 else if (GTK_IS_CONTAINER(connect_widget
))
2541 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2549 bool wxWindow::AcceptsFocus() const
2551 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2554 bool wxWindow::Reparent( wxWindow
*newParent
)
2556 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2558 wxWindow
*oldParent
= m_parent
;
2560 if ( !wxWindowBase::Reparent(newParent
) )
2565 gtk_container_remove( GTK_CONTAINER(oldParent
->m_wxwindow
), m_widget
);
2570 /* insert GTK representation */
2571 (*(newParent
->m_insertCallback
))(newParent
, this);
2577 void wxWindow::DoAddChild(wxWindow
*child
)
2579 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2581 wxASSERT_MSG( (child
!= NULL
), _T("invalid child window") );
2583 wxASSERT_MSG( (m_insertCallback
!= NULL
), _T("invalid child insertion function") );
2588 /* insert GTK representation */
2589 (*m_insertCallback
)(this, child
);
2592 void wxWindow::Raise()
2594 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2596 if (!m_widget
->window
) return;
2598 gdk_window_raise( m_widget
->window
);
2601 void wxWindow::Lower()
2603 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2605 if (!m_widget
->window
) return;
2607 gdk_window_lower( m_widget
->window
);
2610 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2612 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2614 if (!wxWindowBase::SetCursor(cursor
))
2616 // don't leave if the GTK widget has just
2618 if (!m_delayedCursor
) return FALSE
;
2621 GtkWidget
*connect_widget
= GetConnectWidget();
2622 if (!connect_widget
->window
)
2624 // indicate that a new style has been set
2625 // but it couldn't get applied as the
2626 // widget hasn't been realized yet.
2627 m_delayedCursor
= TRUE
;
2629 // pretend we have done something
2633 // gdk_window_set_cursor( connect_widget->window, GetCursor().GetCursor() );
2639 void wxWindow::WarpPointer( int x
, int y
)
2641 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2643 GtkWidget
*connect_widget
= GetConnectWidget();
2644 if (connect_widget
->window
)
2646 /* we provide this function ourselves as it is
2648 gdk_window_warp_pointer( connect_widget
->window
, x
, y
);
2652 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2654 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2656 if (!m_widget
->window
) return;
2658 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2662 gdk_window_clear_area( m_wxwindow
->window
,
2664 rect
->width
, rect
->height
);
2668 gdk_window_clear( m_wxwindow
->window
);
2675 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2677 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2681 GdkRectangle gdk_rect
;
2682 gdk_rect
.x
= rect
->x
;
2683 gdk_rect
.y
= rect
->y
;
2684 gdk_rect
.width
= rect
->width
;
2685 gdk_rect
.height
= rect
->height
;
2688 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2690 gtk_widget_draw( m_widget
, &gdk_rect
);
2694 void wxWindow::Clear()
2696 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2698 if (!m_widget
->window
) return;
2700 if (m_wxwindow
&& m_wxwindow
->window
)
2702 gdk_window_clear( m_wxwindow
->window
);
2707 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2709 wxWindowBase::DoSetToolTip(tip
);
2712 m_tooltip
->Apply( this );
2715 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2717 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2719 #endif // wxUSE_TOOLTIPS
2721 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2723 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2725 if (!wxWindowBase::SetBackgroundColour(colour
))
2727 // don't leave if the GTK widget has just
2729 if (!m_delayedBackgroundColour
) return FALSE
;
2732 GtkWidget
*connect_widget
= GetConnectWidget();
2733 if (!connect_widget
->window
)
2735 // indicate that a new style has been set
2736 // but it couldn't get applied as the
2737 // widget hasn't been realized yet.
2738 m_delayedBackgroundColour
= TRUE
;
2740 // pretend we have done something
2744 if (m_wxwindow
&& m_wxwindow
->window
)
2746 /* wxMSW doesn't clear the window here. I don't do that either to
2747 provide compatibility. call Clear() to do the job. */
2749 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2750 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2753 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2754 if (sysbg
== m_backgroundColour
)
2756 m_backgroundColour
= wxNullColour
;
2758 m_backgroundColour
= sysbg
;
2768 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2770 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2772 if (!wxWindowBase::SetForegroundColour(colour
))
2774 // don't leave if the GTK widget has just
2776 if (!m_delayedForegroundColour
) return FALSE
;
2779 GtkWidget
*connect_widget
= GetConnectWidget();
2780 if (!connect_widget
->window
)
2782 // indicate that a new style has been set
2783 // but it couldn't get applied as the
2784 // widget hasn't been realized yet.
2785 m_delayedForegroundColour
= TRUE
;
2787 // pretend we have done something
2791 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2792 if ( sysbg
== m_backgroundColour
)
2794 m_backgroundColour
= wxNullColour
;
2796 m_backgroundColour
= sysbg
;
2806 GtkStyle
*wxWindow::GetWidgetStyle()
2808 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2810 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2812 return m_widgetStyle
;
2815 void wxWindow::SetWidgetStyle()
2817 GtkStyle
*style
= GetWidgetStyle();
2819 gdk_font_unref( style
->font
);
2820 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2822 if (m_foregroundColour
.Ok())
2824 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2825 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2826 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2827 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2830 if (m_backgroundColour
.Ok())
2832 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2833 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2834 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2835 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2836 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2837 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2838 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2839 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2840 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2844 void wxWindow::ApplyWidgetStyle()
2848 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2850 menu
->SetInvokingWindow( win
);
2851 wxNode
*node
= menu
->GetItems().First();
2854 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2855 if (menuitem
->IsSubMenu())
2857 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2859 node
= node
->Next();
2863 static gint gs_pop_x
= 0;
2864 static gint gs_pop_y
= 0;
2866 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2870 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2875 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
2877 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2879 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2881 SetInvokingWindow( menu
, this );
2889 GTK_MENU(menu
->m_menu
),
2890 (GtkWidget
*) NULL
, // parent menu shell
2891 (GtkWidget
*) NULL
, // parent menu item
2892 (GtkMenuPositionFunc
) pop_pos_callback
,
2893 (gpointer
) this, // client data
2894 0, // button used to activate it
2895 0 //gs_timeLastClick // the time of activation
2900 #if wxUSE_DRAG_AND_DROP
2902 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2904 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2906 GtkWidget
*dnd_widget
= GetConnectWidget();
2908 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2910 if (m_dropTarget
) delete m_dropTarget
;
2911 m_dropTarget
= dropTarget
;
2913 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2916 #endif // wxUSE_DRAG_AND_DROP
2918 GtkWidget
* wxWindow::GetConnectWidget()
2920 GtkWidget
*connect_widget
= m_widget
;
2921 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2923 return connect_widget
;
2926 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2928 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2929 return (window
== m_widget
->window
);
2932 bool wxWindow::SetFont( const wxFont
&font
)
2934 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T( "invalid window") );
2936 if (!wxWindowBase::SetFont(font
))
2938 // don't leave if the GTK widget has just
2940 if (!m_delayedFont
) return FALSE
;
2943 GtkWidget
*connect_widget
= GetConnectWidget();
2944 if (!connect_widget
->window
)
2946 // indicate that a new style has been set
2947 // but it couldn't get applied as the
2948 // widget hasn't been realized yet.
2949 m_delayedFont
= TRUE
;
2951 // pretend we have done something
2955 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2956 if ( sysbg
== m_backgroundColour
)
2958 m_backgroundColour
= wxNullColour
;
2960 m_backgroundColour
= sysbg
;
2970 void wxWindow::CaptureMouse()
2972 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2974 wxCHECK_RET( g_captureWindow
== NULL
, _T("CaptureMouse called twice") );
2976 GtkWidget
*connect_widget
= GetConnectWidget();
2977 if (!connect_widget
->window
) return;
2979 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2981 (GDK_BUTTON_PRESS_MASK
|
2982 GDK_BUTTON_RELEASE_MASK
|
2983 GDK_POINTER_MOTION_MASK
),
2985 m_cursor
.GetCursor(),
2987 g_captureWindow
= this;
2990 void wxWindow::ReleaseMouse()
2992 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2994 wxCHECK_RET( g_captureWindow
, _T("ReleaseMouse called twice") );
2996 GtkWidget
*connect_widget
= GetConnectWidget();
2997 if (!connect_widget
->window
) return;
2999 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3000 g_captureWindow
= (wxWindow
*) NULL
;
3003 bool wxWindow::IsRetained() const
3008 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3009 int range
, bool refresh
)
3011 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3013 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3015 m_hasScrolling
= TRUE
;
3017 if (orient
== wxHORIZONTAL
)
3019 float fpos
= (float)pos
;
3020 float frange
= (float)range
;
3021 float fthumb
= (float)thumbVisible
;
3022 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3023 if (fpos
< 0.0) fpos
= 0.0;
3025 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3026 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3028 SetScrollPos( orient
, pos
, refresh
);
3032 m_oldHorizontalPos
= fpos
;
3034 m_hAdjust
->lower
= 0.0;
3035 m_hAdjust
->upper
= frange
;
3036 m_hAdjust
->value
= fpos
;
3037 m_hAdjust
->step_increment
= 1.0;
3038 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3039 m_hAdjust
->page_size
= fthumb
;
3043 float fpos
= (float)pos
;
3044 float frange
= (float)range
;
3045 float fthumb
= (float)thumbVisible
;
3046 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3047 if (fpos
< 0.0) fpos
= 0.0;
3049 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3050 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3052 SetScrollPos( orient
, pos
, refresh
);
3056 m_oldVerticalPos
= fpos
;
3058 m_vAdjust
->lower
= 0.0;
3059 m_vAdjust
->upper
= frange
;
3060 m_vAdjust
->value
= fpos
;
3061 m_vAdjust
->step_increment
= 1.0;
3062 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3063 m_vAdjust
->page_size
= fthumb
;
3066 if (orient
== wxHORIZONTAL
)
3067 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3069 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3072 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3074 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3076 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3078 if (orient
== wxHORIZONTAL
)
3080 float fpos
= (float)pos
;
3081 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3082 if (fpos
< 0.0) fpos
= 0.0;
3083 m_oldHorizontalPos
= fpos
;
3085 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3086 m_hAdjust
->value
= fpos
;
3090 float fpos
= (float)pos
;
3091 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3092 if (fpos
< 0.0) fpos
= 0.0;
3093 m_oldVerticalPos
= fpos
;
3095 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3096 m_vAdjust
->value
= fpos
;
3099 if (!m_isScrolling
) /* prevent recursion */
3101 if (m_wxwindow
->window
)
3103 if (orient
== wxHORIZONTAL
)
3104 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3106 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3111 int wxWindow::GetScrollThumb( int orient
) const
3113 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3115 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3117 if (orient
== wxHORIZONTAL
)
3118 return (int)(m_hAdjust
->page_size
+0.5);
3120 return (int)(m_vAdjust
->page_size
+0.5);
3123 int wxWindow::GetScrollPos( int orient
) const
3125 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3127 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3129 if (orient
== wxHORIZONTAL
)
3130 return (int)(m_hAdjust
->value
+0.5);
3132 return (int)(m_vAdjust
->value
+0.5);
3135 int wxWindow::GetScrollRange( int orient
) const
3137 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3139 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3141 if (orient
== wxHORIZONTAL
)
3142 return (int)(m_hAdjust
->upper
+0.5);
3144 return (int)(m_vAdjust
->upper
+0.5);
3147 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3149 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3151 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3155 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3156 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3159 wxNode
*node
= m_children
.First();
3162 wxWindow
*child
= (wxWindow
*) node
->Data();
3165 child
->GetSize( &sx
, &sy
);
3166 child
->SetSize( child
->m_x
+ dx
, child
->m_y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
3167 node
= node
->Next();
3172 GetClientSize( &cw
, &ch
);
3173 int w
= cw
- abs(dx
);
3174 int h
= ch
- abs(dy
);
3176 if ((h
< 0) || (w
< 0))
3184 if (dx
< 0) s_x
= -dx
;
3185 if (dy
< 0) s_y
= -dy
;
3188 if (dx
> 0) d_x
= dx
;
3189 if (dy
> 0) d_y
= dy
;
3191 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3192 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3195 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3196 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3197 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3198 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3200 Refresh( TRUE
, &rect
);
3204 void wxWindow::SetScrolling(bool scroll
)
3206 m_isScrolling
= g_blockEventsOnScroll
= scroll
;