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 wxCursor cursor
= m_cursor
;
2195 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2197 if (cursor
.Ok() && m_currentGdkCursor
!= cursor
)
2201 GdkWindow
*window
= m_wxwindow
->window
;
2203 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2205 if (!g_globalCursor
.Ok())
2206 cursor
= *wxSTANDARD_CURSOR
;
2208 window
= m_widget
->window
;
2210 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2214 GdkWindow
*window
= m_widget
->window
;
2216 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2219 m_currentGdkCursor
= cursor
;
2225 void wxWindow::DoGetSize( int *width
, int *height
) const
2227 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2229 if (width
) (*width
) = m_width
;
2230 if (height
) (*height
) = m_height
;
2233 void wxWindow::DoSetClientSize( int width
, int height
)
2235 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2239 SetSize( width
, height
);
2246 if (!m_hasScrolling
)
2248 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2250 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2252 dw
+= 2 * window_class
->xthickness
;
2253 dh
+= 2 * window_class
->ythickness
;
2258 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2259 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2261 #if (GTK_MINOR_VERSION == 0)
2262 GtkWidget
*viewport
= scroll_window
->viewport
;
2263 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2265 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2267 dw
+= 2 * viewport_class
->xthickness
;
2268 dh
+= 2 * viewport_class
->ythickness
;
2273 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2274 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2276 we use this instead: range.slider_width = 11 + 2*2pts edge
2279 if (scroll_window
->vscrollbar_visible
)
2281 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2282 dw
+= scroll_class
->scrollbar_spacing
;
2285 if (scroll_window
->hscrollbar_visible
)
2287 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2288 dh
+= scroll_class
->scrollbar_spacing
;
2292 SetSize( width
+dw
, height
+dh
);
2296 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2298 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2302 if (width
) (*width
) = m_width
;
2303 if (height
) (*height
) = m_height
;
2310 if (!m_hasScrolling
)
2312 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2314 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2316 dw
+= 2 * window_class
->xthickness
;
2317 dh
+= 2 * window_class
->ythickness
;
2322 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2323 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2325 #if (GTK_MINOR_VERSION == 0)
2326 GtkWidget
*viewport
= scroll_window
->viewport
;
2327 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2329 if ( HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
) )
2331 dw
+= 2 * viewport_class
->xthickness
;
2332 dh
+= 2 * viewport_class
->ythickness
;
2336 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2337 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2339 we use this instead: range.slider_width = 11 + 2*2pts edge
2342 if (scroll_window
->vscrollbar_visible
)
2344 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2345 dw
+= scroll_class
->scrollbar_spacing
;
2348 if (scroll_window
->hscrollbar_visible
)
2350 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2351 dh
+= scroll_class
->scrollbar_spacing
;
2355 if (width
) (*width
) = m_width
- dw
;
2356 if (height
) (*height
) = m_height
- dh
;
2360 void wxWindow::DoGetPosition( int *x
, int *y
) const
2362 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2368 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2370 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2372 if (!m_widget
->window
) return;
2374 GdkWindow
*source
= (GdkWindow
*) NULL
;
2376 source
= m_wxwindow
->window
;
2378 source
= m_widget
->window
;
2382 gdk_window_get_origin( source
, &org_x
, &org_y
);
2386 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2388 org_x
+= m_widget
->allocation
.x
;
2389 org_y
+= m_widget
->allocation
.y
;
2397 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2399 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2401 if (!m_widget
->window
) return;
2403 GdkWindow
*source
= (GdkWindow
*) NULL
;
2405 source
= m_wxwindow
->window
;
2407 source
= m_widget
->window
;
2411 gdk_window_get_origin( source
, &org_x
, &org_y
);
2415 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2417 org_x
+= m_widget
->allocation
.x
;
2418 org_y
+= m_widget
->allocation
.y
;
2426 bool wxWindow::Show( bool show
)
2428 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2430 if (!wxWindowBase::Show(show
))
2437 gtk_widget_show( m_widget
);
2439 gtk_widget_hide( m_widget
);
2444 bool wxWindow::Enable( bool enable
)
2446 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2448 if (!wxWindowBase::Enable(enable
))
2454 gtk_widget_set_sensitive( m_widget
, enable
);
2456 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2461 int wxWindow::GetCharHeight() const
2463 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2465 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2467 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2469 return font
->ascent
+ font
->descent
;
2472 int wxWindow::GetCharWidth() const
2474 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2476 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2478 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2480 return gdk_string_width( font
, "H" );
2483 void wxWindow::GetTextExtent( const wxString
& string
,
2487 int *externalLeading
,
2488 const wxFont
*theFont
) const
2490 wxFont fontToUse
= m_font
;
2491 if (theFont
) fontToUse
= *theFont
;
2493 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2495 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2496 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2497 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2498 if (descent
) (*descent
) = font
->descent
;
2499 if (externalLeading
) (*externalLeading
) = 0; // ??
2502 void wxWindow::SetFocus()
2504 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2506 GtkWidget
*connect_widget
= GetConnectWidget();
2509 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2511 gtk_widget_grab_focus (connect_widget
);
2513 else if (GTK_IS_CONTAINER(connect_widget
))
2515 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2523 bool wxWindow::AcceptsFocus() const
2525 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2528 bool wxWindow::Reparent( wxWindow
*newParent
)
2530 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2532 wxWindow
*oldParent
= m_parent
;
2534 if ( !wxWindowBase::Reparent(newParent
) )
2539 gtk_container_remove( GTK_CONTAINER(oldParent
->m_wxwindow
), m_widget
);
2544 /* insert GTK representation */
2545 (*(newParent
->m_insertCallback
))(newParent
, this);
2551 void wxWindow::DoAddChild(wxWindow
*child
)
2553 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2555 wxASSERT_MSG( (child
!= NULL
), _T("invalid child window") );
2557 wxASSERT_MSG( (m_insertCallback
!= NULL
), _T("invalid child insertion function") );
2562 /* insert GTK representation */
2563 (*m_insertCallback
)(this, child
);
2566 void wxWindow::Raise()
2568 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2570 if (!m_widget
->window
) return;
2572 gdk_window_raise( m_widget
->window
);
2575 void wxWindow::Lower()
2577 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2579 if (!m_widget
->window
) return;
2581 gdk_window_lower( m_widget
->window
);
2584 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2586 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2588 if (!wxWindowBase::SetCursor(cursor
))
2590 // don't leave if the GTK widget has just
2592 if (!m_delayedCursor
) return FALSE
;
2595 GtkWidget
*connect_widget
= GetConnectWidget();
2596 if (!connect_widget
->window
)
2598 // indicate that a new style has been set
2599 // but it couldn't get applied as the
2600 // widget hasn't been realized yet.
2601 m_delayedCursor
= TRUE
;
2603 // pretend we have done something
2607 // gdk_window_set_cursor( connect_widget->window, GetCursor().GetCursor() );
2613 void wxWindow::WarpPointer( int x
, int y
)
2615 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2617 GtkWidget
*connect_widget
= GetConnectWidget();
2618 if (connect_widget
->window
)
2620 /* we provide this function ourselves as it is
2622 gdk_window_warp_pointer( connect_widget
->window
, x
, y
);
2626 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2628 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2630 if (!m_widget
->window
) return;
2632 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2636 gdk_window_clear_area( m_wxwindow
->window
,
2638 rect
->width
, rect
->height
);
2642 gdk_window_clear( m_wxwindow
->window
);
2649 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2651 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2655 GdkRectangle gdk_rect
;
2656 gdk_rect
.x
= rect
->x
;
2657 gdk_rect
.y
= rect
->y
;
2658 gdk_rect
.width
= rect
->width
;
2659 gdk_rect
.height
= rect
->height
;
2662 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2664 gtk_widget_draw( m_widget
, &gdk_rect
);
2668 void wxWindow::Clear()
2670 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2672 if (!m_widget
->window
) return;
2674 if (m_wxwindow
&& m_wxwindow
->window
)
2676 gdk_window_clear( m_wxwindow
->window
);
2681 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2683 wxWindowBase::DoSetToolTip(tip
);
2686 m_tooltip
->Apply( this );
2689 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2691 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2693 #endif // wxUSE_TOOLTIPS
2695 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2697 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2699 if (!wxWindowBase::SetBackgroundColour(colour
))
2701 // don't leave if the GTK widget has just
2703 if (!m_delayedBackgroundColour
) return FALSE
;
2706 GtkWidget
*connect_widget
= GetConnectWidget();
2707 if (!connect_widget
->window
)
2709 // indicate that a new style has been set
2710 // but it couldn't get applied as the
2711 // widget hasn't been realized yet.
2712 m_delayedBackgroundColour
= TRUE
;
2714 // pretend we have done something
2718 if (m_wxwindow
&& m_wxwindow
->window
)
2720 /* wxMSW doesn't clear the window here. I don't do that either to
2721 provide compatibility. call Clear() to do the job. */
2723 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2724 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2727 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2728 if (sysbg
== m_backgroundColour
)
2730 m_backgroundColour
= wxNullColour
;
2732 m_backgroundColour
= sysbg
;
2742 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2744 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2746 if (!wxWindowBase::SetForegroundColour(colour
))
2748 // don't leave if the GTK widget has just
2750 if (!m_delayedForegroundColour
) return FALSE
;
2753 GtkWidget
*connect_widget
= GetConnectWidget();
2754 if (!connect_widget
->window
)
2756 // indicate that a new style has been set
2757 // but it couldn't get applied as the
2758 // widget hasn't been realized yet.
2759 m_delayedForegroundColour
= TRUE
;
2761 // pretend we have done something
2765 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2766 if ( sysbg
== m_backgroundColour
)
2768 m_backgroundColour
= wxNullColour
;
2770 m_backgroundColour
= sysbg
;
2780 GtkStyle
*wxWindow::GetWidgetStyle()
2782 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2784 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2786 return m_widgetStyle
;
2789 void wxWindow::SetWidgetStyle()
2791 GtkStyle
*style
= GetWidgetStyle();
2793 gdk_font_unref( style
->font
);
2794 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2796 if (m_foregroundColour
.Ok())
2798 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2799 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2800 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2801 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2804 if (m_backgroundColour
.Ok())
2806 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2807 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2808 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2809 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2810 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2811 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2812 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2813 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2814 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2818 void wxWindow::ApplyWidgetStyle()
2822 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2824 menu
->SetInvokingWindow( win
);
2825 wxNode
*node
= menu
->GetItems().First();
2828 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2829 if (menuitem
->IsSubMenu())
2831 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2833 node
= node
->Next();
2837 static gint gs_pop_x
= 0;
2838 static gint gs_pop_y
= 0;
2840 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2844 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2849 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2851 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2853 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2855 SetInvokingWindow( menu
, this );
2863 GTK_MENU(menu
->m_menu
),
2864 (GtkWidget
*) NULL
, // parent menu shell
2865 (GtkWidget
*) NULL
, // parent menu item
2866 (GtkMenuPositionFunc
) pop_pos_callback
,
2867 (gpointer
) this, // client data
2868 0, // button used to activate it
2869 0 //gs_timeLastClick // the time of activation
2874 #if wxUSE_DRAG_AND_DROP
2876 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2878 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2880 GtkWidget
*dnd_widget
= GetConnectWidget();
2882 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2884 if (m_dropTarget
) delete m_dropTarget
;
2885 m_dropTarget
= dropTarget
;
2887 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2890 #endif // wxUSE_DRAG_AND_DROP
2892 GtkWidget
* wxWindow::GetConnectWidget()
2894 GtkWidget
*connect_widget
= m_widget
;
2895 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2897 return connect_widget
;
2900 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2902 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2903 return (window
== m_widget
->window
);
2906 bool wxWindow::SetFont( const wxFont
&font
)
2908 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T( "invalid window") );
2910 if (!wxWindowBase::SetFont(font
))
2912 // don't leave if the GTK widget has just
2914 if (!m_delayedFont
) return FALSE
;
2917 GtkWidget
*connect_widget
= GetConnectWidget();
2918 if (!connect_widget
->window
)
2920 // indicate that a new style has been set
2921 // but it couldn't get applied as the
2922 // widget hasn't been realized yet.
2923 m_delayedFont
= TRUE
;
2925 // pretend we have done something
2929 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2930 if ( sysbg
== m_backgroundColour
)
2932 m_backgroundColour
= wxNullColour
;
2934 m_backgroundColour
= sysbg
;
2944 void wxWindow::CaptureMouse()
2946 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2948 wxCHECK_RET( g_captureWindow
== NULL
, _T("CaptureMouse called twice") );
2950 GtkWidget
*connect_widget
= GetConnectWidget();
2951 if (!connect_widget
->window
) return;
2953 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2955 (GDK_BUTTON_PRESS_MASK
|
2956 GDK_BUTTON_RELEASE_MASK
|
2957 GDK_POINTER_MOTION_MASK
),
2959 m_cursor
.GetCursor(),
2961 g_captureWindow
= this;
2964 void wxWindow::ReleaseMouse()
2966 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2968 wxCHECK_RET( g_captureWindow
, _T("ReleaseMouse called twice") );
2970 GtkWidget
*connect_widget
= GetConnectWidget();
2971 if (!connect_widget
->window
) return;
2973 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2974 g_captureWindow
= (wxWindow
*) NULL
;
2977 bool wxWindow::IsRetained() const
2982 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2983 int range
, bool refresh
)
2985 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2987 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
2989 m_hasScrolling
= TRUE
;
2991 if (orient
== wxHORIZONTAL
)
2993 float fpos
= (float)pos
;
2994 float frange
= (float)range
;
2995 float fthumb
= (float)thumbVisible
;
2996 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2997 if (fpos
< 0.0) fpos
= 0.0;
2999 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3000 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3002 SetScrollPos( orient
, pos
, refresh
);
3006 m_oldHorizontalPos
= fpos
;
3008 m_hAdjust
->lower
= 0.0;
3009 m_hAdjust
->upper
= frange
;
3010 m_hAdjust
->value
= fpos
;
3011 m_hAdjust
->step_increment
= 1.0;
3012 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3013 m_hAdjust
->page_size
= fthumb
;
3017 float fpos
= (float)pos
;
3018 float frange
= (float)range
;
3019 float fthumb
= (float)thumbVisible
;
3020 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3021 if (fpos
< 0.0) fpos
= 0.0;
3023 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3024 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3026 SetScrollPos( orient
, pos
, refresh
);
3030 m_oldVerticalPos
= fpos
;
3032 m_vAdjust
->lower
= 0.0;
3033 m_vAdjust
->upper
= frange
;
3034 m_vAdjust
->value
= fpos
;
3035 m_vAdjust
->step_increment
= 1.0;
3036 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3037 m_vAdjust
->page_size
= fthumb
;
3040 if (orient
== wxHORIZONTAL
)
3041 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3043 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3046 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3048 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3050 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3052 if (orient
== wxHORIZONTAL
)
3054 float fpos
= (float)pos
;
3055 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3056 if (fpos
< 0.0) fpos
= 0.0;
3057 m_oldHorizontalPos
= fpos
;
3059 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3060 m_hAdjust
->value
= fpos
;
3064 float fpos
= (float)pos
;
3065 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3066 if (fpos
< 0.0) fpos
= 0.0;
3067 m_oldVerticalPos
= fpos
;
3069 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3070 m_vAdjust
->value
= fpos
;
3073 if (!m_isScrolling
) /* prevent recursion */
3075 if (m_wxwindow
->window
)
3077 if (orient
== wxHORIZONTAL
)
3078 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3080 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3085 int wxWindow::GetScrollThumb( int orient
) const
3087 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3089 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3091 if (orient
== wxHORIZONTAL
)
3092 return (int)(m_hAdjust
->page_size
+0.5);
3094 return (int)(m_vAdjust
->page_size
+0.5);
3097 int wxWindow::GetScrollPos( int orient
) const
3099 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3101 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3103 if (orient
== wxHORIZONTAL
)
3104 return (int)(m_hAdjust
->value
+0.5);
3106 return (int)(m_vAdjust
->value
+0.5);
3109 int wxWindow::GetScrollRange( int orient
) const
3111 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3113 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3115 if (orient
== wxHORIZONTAL
)
3116 return (int)(m_hAdjust
->upper
+0.5);
3118 return (int)(m_vAdjust
->upper
+0.5);
3121 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3123 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3125 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3129 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3130 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3133 wxNode
*node
= m_children
.First();
3136 wxWindow
*child
= (wxWindow
*) node
->Data();
3139 child
->GetSize( &sx
, &sy
);
3140 child
->SetSize( child
->m_x
+ dx
, child
->m_y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
3141 node
= node
->Next();
3146 GetClientSize( &cw
, &ch
);
3147 int w
= cw
- abs(dx
);
3148 int h
= ch
- abs(dy
);
3150 if ((h
< 0) || (w
< 0))
3158 if (dx
< 0) s_x
= -dx
;
3159 if (dy
< 0) s_y
= -dy
;
3162 if (dx
> 0) d_x
= dx
;
3163 if (dy
> 0) d_y
= dy
;
3165 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3166 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3169 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3170 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3171 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3172 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3174 Refresh( TRUE
, &rect
);
3178 void wxWindow::SetScrolling(bool scroll
)
3180 m_isScrolling
= g_blockEventsOnScroll
= scroll
;