1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "window.h"
16 #include "wx/window.h"
20 #include "wx/layout.h"
22 #include "wx/dialog.h"
23 #include "wx/msgdlg.h"
25 #if wxUSE_DRAG_AND_DROP
30 #include "wx/tooltip.h"
34 #include "wx/statusbr.h"
36 #include "wx/settings.h"
43 #include "gdk/gdkprivate.h"
44 #include "gdk/gdkkeysyms.h"
45 #include "wx/gtk/win_gtk.h"
49 //-----------------------------------------------------------------------------
50 // documentation on internals
51 //-----------------------------------------------------------------------------
54 I have been asked several times about writing some documentation about
55 the GTK port of wxWindows, especially its internal structures. Obviously,
56 you cannot understand wxGTK without knowing a little about the GTK, but
57 some more information about what the wxWindow, which is the base class
58 for all other window classes, does seems required as well.
60 What does wxWindow do? It contains the common interface for the following
61 jobs of its descendants:
63 1) Define the rudimentary behaviour common to all window classes, such as
64 resizing, intercepting user input (so as to make it possible to use these
65 events for special purposes in a derived class), window names etc.
67 2) Provide the possibility to contain and manage children, if the derived
68 class is allowed to contain children, which holds true for those window
69 classes which do not display a native GTK widget. To name them, these
70 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
71 work classes are a special case and are handled a bit differently from
72 the rest. The same holds true for the wxNotebook class.
74 3) Provide the possibility to draw into a client area of a window. This,
75 too, only holds true for classes that do not display a native GTK widget
78 4) Provide the entire mechanism for scrolling widgets. This actual inter-
79 face for this is usually in wxScrolledWindow, but the GTK implementation
82 5) A multitude of helper or extra methods for special purposes, such as
83 Drag'n'Drop, managing validators etc.
85 Normally one might expect, that one wxWindows window would always correspond
86 to one GTK widget. Under GTK, there is no such allround widget that has all
87 the functionality. Moreover, the GTK defines a client area as a different
88 widget from the actual widget you are handling. Last but not least some
89 special classes (e.g. wxFrame) handle different categories of widgets and
90 still have the possibility to draw something in the client area.
91 It was therefore required to write a special purpose GTK widget, that would
92 represent a client area in the sense of wxWindows capable to do the jobs
93 2), 3) and 4). I have written this class and it resides in win_gtk.c of
96 All windows must have a widget, with which they interact with other under-
97 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
98 thw wxWindow class has a member variable called m_widget which holds a
99 pointer to this widget. When the window class represents a GTK native widget,
100 this is (in most cases) the only GTK widget the class manages. E.g. the
101 wxStatitText class handles only a GtkLabel widget a pointer to which you
102 can find in m_widget (defined in wxWindow)
104 When the class has a client area for drawing into and for containing children
105 it has to handle the client area widget (of the type GtkMyFixed, defined in
106 win_gtk.c), but there could be any number of widgets, handled by a class
107 The common rule for all windows is only, that the widget that interacts with
108 the rest of GTK must be referenced in m_widget and all other widgets must be
109 children of this widget on the GTK level. The top-most widget, which also
110 represents the client area, must be in the m_wxwindow field and must be of
113 As I said, the window classes that display a GTK native widget only have
114 one widget, so in the case of e.g. the wxButton class m_widget holds a
115 pointer to a GtkButton widget. But windows with client areas (for drawing
116 and children) have a m_widget field that is a pointer to a GtkScrolled-
117 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
118 one is (in the GTK sense) a child of the GtkScrolledWindow.
120 If the m_wxwindow field is set, then all input to this widget is inter-
121 cepted and sent to the wxWindows class. If not, all input to the widget
122 that gets pointed to by m_widget gets intercepted and sent to the class.
126 //-----------------------------------------------------------------------------
128 //-----------------------------------------------------------------------------
130 extern wxList wxPendingDelete
;
131 extern bool g_blockEventsOnDrag
;
132 extern bool g_blockEventsOnScroll
;
133 extern wxCursor g_globalCursor
;
134 static wxWindow
*g_captureWindow
= (wxWindow
*) NULL
;
135 wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
137 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
138 the last click here */
139 static guint32 gs_timeLastClick
= 0;
141 //-----------------------------------------------------------------------------
143 //-----------------------------------------------------------------------------
147 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
148 GdkEvent
*WXUNUSED(event
),
149 const wxChar
*WXUNUSED(name
) )
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
);
636 if (win
->HasFlag(wxSIMPLE_BORDER
))
638 GdkGC
*gc
= gdk_gc_new( widget
->window
);
639 gdk_gc_set_foreground( gc
, &widget
->style
->black
);
640 gdk_draw_rectangle( widget
->window
, gc
, FALSE
,
642 win
->m_width
-dw
-1, win
->m_height
-dh
-1 );
648 //-----------------------------------------------------------------------------
649 // "expose_event" of m_widget
650 //-----------------------------------------------------------------------------
652 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
654 if (gdk_event
->count
> 0) return;
655 draw_frame( widget
, win
);
658 //-----------------------------------------------------------------------------
659 // "draw" of m_wxwindow
660 //-----------------------------------------------------------------------------
662 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
664 draw_frame( widget
, win
);
667 #endif // GTK_MINOR_VERSION > 0
669 //-----------------------------------------------------------------------------
670 // "expose_event" of m_wxwindow
671 //-----------------------------------------------------------------------------
673 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
678 if (gdk_event
->window
!= win
->m_wxwindow
->window
)
681 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
683 gdk_event
->area
.width
,
684 gdk_event
->area
.height
);
686 if (gdk_event
->count
> 0)
689 wxPaintEvent
event( win
->GetId() );
690 event
.SetEventObject( win
);
691 win
->GetEventHandler()->ProcessEvent( event
);
694 wxPrintf( "OnExpose from " );
695 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
696 wxPrintf( win->GetClassInfo()->GetClassName() );
697 wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x,
698 (int)gdk_event->area.y,
699 (int)gdk_event->area.width,
700 (int)gdk_event->area.height );
703 win
->GetUpdateRegion().Clear();
706 //-----------------------------------------------------------------------------
707 // "draw" of m_wxwindow
708 //-----------------------------------------------------------------------------
710 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
713 wxapp_install_idle_handler();
718 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
719 rect
->width
, rect
->height
);
721 wxPaintEvent
event( win
->GetId() );
722 event
.SetEventObject( win
);
725 wxPrintf( "OnDraw from " );
726 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
727 printf( win->GetClassInfo()->GetClassName() );
728 wxPrintf( " %d %d %d %d\n", (int)rect->x,
734 win
->GetEventHandler()->ProcessEvent( event
);
736 win
->GetUpdateRegion().Clear();
739 //-----------------------------------------------------------------------------
740 // "key_press_event" from any window
741 //-----------------------------------------------------------------------------
743 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
746 wxapp_install_idle_handler();
748 if (!win
->m_hasVMT
) return FALSE
;
749 if (g_blockEventsOnDrag
) return FALSE
;
752 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
753 if (gdk_event->state & GDK_SHIFT_MASK)
754 printf( "ShiftDown.\n" );
756 printf( "ShiftUp.\n" );
757 if (gdk_event->state & GDK_CONTROL_MASK)
758 printf( "ControlDown.\n" );
760 printf( "ControlUp.\n" );
765 GdkModifierType state
;
766 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
768 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
770 /* sending unknown key events doesn't really make sense */
771 if (key_code
== 0) return FALSE
;
775 wxKeyEvent
event( wxEVT_KEY_DOWN
);
776 event
.SetTimestamp( gdk_event
->time
);
777 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
778 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
779 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
780 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
781 event
.m_keyCode
= key_code
;
782 event
.m_scanCode
= gdk_event
->keyval
;
785 event
.SetEventObject( win
);
786 ret
= win
->GetEventHandler()->ProcessEvent( event
);
788 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
793 wxWindow
*ancestor
= win
;
796 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
799 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
800 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
803 ancestor
= ancestor
->GetParent();
806 #endif // wxUSE_ACCEL
807 /* wxMSW doesn't send char events with Alt pressed */
808 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
809 will only be sent if it is not a menu accelerator. */
810 if ((key_code
!= 0) && ! ret
)
812 wxKeyEvent
event2( wxEVT_CHAR
);
813 event2
.SetTimestamp( gdk_event
->time
);
814 event2
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
815 event2
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
816 event2
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
817 event2
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
818 event2
.m_keyCode
= key_code
;
819 event2
.m_scanCode
= gdk_event
->keyval
;
822 event2
.SetEventObject( win
);
823 ret
= (ret
|| win
->GetEventHandler()->ProcessEvent( event2
));
826 /* win is a control: tab can be propagated up */
828 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
829 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
831 wxNavigationKeyEvent new_event
;
832 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
833 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
834 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
835 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
836 new_event
.SetCurrentFocus( win
);
837 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
840 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
842 (gdk_event
->keyval
== GDK_Escape
) )
844 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
845 new_event
.SetEventObject( win
);
846 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
849 #if (GTK_MINOR_VERSION > 0)
850 /* pressing F10 will activate the menu bar of the top frame */
852 (gdk_event
->keyval
== GDK_F10
) )
854 wxWindow
*ancestor
= win
;
857 if (wxIsKindOf(ancestor
,wxFrame
))
859 wxFrame
*frame
= (wxFrame
*) ancestor
;
860 wxMenuBar
*menubar
= frame
->GetMenuBar();
863 wxNode
*node
= menubar
->GetMenus().First();
866 // doesn't work correctly
867 // wxMenu *firstMenu = (wxMenu*) node->Data();
868 // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
874 ancestor
= ancestor
->GetParent();
880 Damn, I forgot why this didn't work, but it didn't work.
882 // win is a panel: up can be propagated to the panel
883 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
884 (gdk_event->keyval == GDK_Up))
886 win->m_parent->SetFocus();
890 // win is a panel: left/right can be propagated to the panel
891 if ((!ret) && (win->m_wxwindow) &&
892 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
893 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
895 wxNavigationKeyEvent new_event;
896 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
897 new_event.SetCurrentFocus( win );
898 ret = win->GetEventHandler()->ProcessEvent( new_event );
904 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
911 //-----------------------------------------------------------------------------
912 // "key_release_event" from any window
913 //-----------------------------------------------------------------------------
915 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
918 wxapp_install_idle_handler();
920 if (!win
->m_hasVMT
) return FALSE
;
921 if (g_blockEventsOnDrag
) return FALSE
;
924 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
925 if (gdk_event->state & GDK_SHIFT_MASK)
926 printf( "ShiftDown.\n" );
928 printf( "ShiftUp.\n" );
929 if (gdk_event->state & GDK_CONTROL_MASK)
930 printf( "ControlDown.\n" );
932 printf( "ControlUp.\n" );
936 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
938 /* sending unknown key events doesn't really make sense */
939 if (key_code
== 0) return FALSE
;
943 GdkModifierType state
;
944 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
946 wxKeyEvent
event( wxEVT_KEY_UP
);
947 event
.SetTimestamp( gdk_event
->time
);
948 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
949 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
950 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
951 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
952 event
.m_keyCode
= key_code
;
953 event
.m_scanCode
= gdk_event
->keyval
;
956 event
.SetEventObject( win
);
958 if (win
->GetEventHandler()->ProcessEvent( event
))
960 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
967 //-----------------------------------------------------------------------------
968 // "button_press_event"
969 //-----------------------------------------------------------------------------
971 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
974 wxapp_install_idle_handler();
977 wxPrintf( _T("1) OnButtonPress from ") );
978 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
979 wxPrintf( win->GetClassInfo()->GetClassName() );
980 wxPrintf( _T(".\n") );
982 if (!win
->m_hasVMT
) return FALSE
;
983 if (g_blockEventsOnDrag
) return TRUE
;
984 if (g_blockEventsOnScroll
) return TRUE
;
986 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
990 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
992 gtk_widget_grab_focus (win
->m_wxwindow
);
995 wxPrintf( _T("GrabFocus from ") );
996 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
997 wxPrintf( win->GetClassInfo()->GetClassName() );
998 wxPrintf( _T(".\n") );
1005 wxPrintf( _T("2) OnButtonPress from ") );
1006 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1007 wxPrintf( win->GetClassInfo()->GetClassName() );
1008 wxPrintf( _T(".\n") );
1011 wxEventType event_type
= wxEVT_LEFT_DOWN
;
1013 if (gdk_event
->button
== 1)
1015 switch (gdk_event
->type
)
1017 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
1018 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
1022 else if (gdk_event
->button
== 2)
1024 switch (gdk_event
->type
)
1026 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
1027 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
1031 else if (gdk_event
->button
== 3)
1033 switch (gdk_event
->type
)
1035 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
1036 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
1041 wxMouseEvent
event( event_type
);
1042 event
.SetTimestamp( gdk_event
->time
);
1043 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1044 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1045 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1046 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1047 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1048 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1049 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1051 event
.m_x
= (long)gdk_event
->x
;
1052 event
.m_y
= (long)gdk_event
->y
;
1054 // Some control don't have their own X window and thus cannot get
1057 if (!g_captureWindow
)
1059 wxNode
*node
= win
->GetChildren().First();
1062 wxWindow
*child
= (wxWindow
*)node
->Data();
1064 if (child
->m_isStaticBox
)
1066 // wxStaticBox is transparent in the box itself
1069 int xx1
= child
->m_x
;
1070 int yy1
= child
->m_y
;
1071 int xx2
= child
->m_x
+ child
->m_width
;
1072 int yy2
= child
->m_x
+ child
->m_height
;
1075 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1077 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1079 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1081 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1084 event
.m_x
-= child
->m_x
;
1085 event
.m_y
-= child
->m_y
;
1092 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1093 (child
->m_x
<= event
.m_x
) &&
1094 (child
->m_y
<= event
.m_y
) &&
1095 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1096 (child
->m_y
+child
->m_height
>= event
.m_y
))
1099 event
.m_x
-= child
->m_x
;
1100 event
.m_y
-= child
->m_y
;
1104 node
= node
->Next();
1108 event
.SetEventObject( win
);
1110 gs_timeLastClick
= gdk_event
->time
;
1112 if (win
->GetEventHandler()->ProcessEvent( event
))
1114 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
1121 //-----------------------------------------------------------------------------
1122 // "button_release_event"
1123 //-----------------------------------------------------------------------------
1125 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1128 wxapp_install_idle_handler();
1130 if (!win
->m_hasVMT
) return FALSE
;
1131 if (g_blockEventsOnDrag
) return FALSE
;
1132 if (g_blockEventsOnScroll
) return FALSE
;
1134 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1137 printf( "OnButtonRelease from " );
1138 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1139 printf( win->GetClassInfo()->GetClassName() );
1143 wxEventType event_type
= wxEVT_NULL
;
1145 switch (gdk_event
->button
)
1147 case 1: event_type
= wxEVT_LEFT_UP
; break;
1148 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
1149 case 3: event_type
= wxEVT_RIGHT_UP
; break;
1152 wxMouseEvent
event( event_type
);
1153 event
.SetTimestamp( gdk_event
->time
);
1154 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1155 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1156 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1157 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1158 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1159 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1160 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1161 event
.m_x
= (long)gdk_event
->x
;
1162 event
.m_y
= (long)gdk_event
->y
;
1164 // Some control don't have their own X window and thus cannot get
1167 if (!g_captureWindow
)
1169 wxNode
*node
= win
->GetChildren().First();
1172 wxWindow
*child
= (wxWindow
*)node
->Data();
1174 if (child
->m_isStaticBox
)
1176 // wxStaticBox is transparent in the box itself
1179 int xx1
= child
->m_x
;
1180 int yy1
= child
->m_y
;
1181 int xx2
= child
->m_x
+ child
->m_width
;
1182 int yy2
= child
->m_x
+ child
->m_height
;
1185 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1187 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1189 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1191 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1194 event
.m_x
-= child
->m_x
;
1195 event
.m_y
-= child
->m_y
;
1202 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1203 (child
->m_x
<= event
.m_x
) &&
1204 (child
->m_y
<= event
.m_y
) &&
1205 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1206 (child
->m_y
+child
->m_height
>= event
.m_y
))
1209 event
.m_x
-= child
->m_x
;
1210 event
.m_y
-= child
->m_y
;
1214 node
= node
->Next();
1218 event
.SetEventObject( win
);
1220 if (win
->GetEventHandler()->ProcessEvent( event
))
1222 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1229 //-----------------------------------------------------------------------------
1230 // "motion_notify_event"
1231 //-----------------------------------------------------------------------------
1233 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1236 wxapp_install_idle_handler();
1238 if (!win
->m_hasVMT
) return FALSE
;
1239 if (g_blockEventsOnDrag
) return FALSE
;
1240 if (g_blockEventsOnScroll
) return FALSE
;
1242 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1244 if (gdk_event
->is_hint
)
1248 GdkModifierType state
;
1249 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1252 gdk_event
->state
= state
;
1256 printf( "OnMotion from " );
1257 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1258 printf( win->GetClassInfo()->GetClassName() );
1262 wxMouseEvent
event( wxEVT_MOTION
);
1263 event
.SetTimestamp( gdk_event
->time
);
1264 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1265 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1266 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1267 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1268 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1269 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1270 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1272 event
.m_x
= (long)gdk_event
->x
;
1273 event
.m_y
= (long)gdk_event
->y
;
1275 // Some control don't have their own X window and thus cannot get
1278 if (!g_captureWindow
)
1280 wxNode
*node
= win
->GetChildren().First();
1283 wxWindow
*child
= (wxWindow
*)node
->Data();
1285 if (child
->m_isStaticBox
)
1287 // wxStaticBox is transparent in the box itself
1290 int xx1
= child
->m_x
;
1291 int yy1
= child
->m_y
;
1292 int xx2
= child
->m_x
+ child
->m_width
;
1293 int yy2
= child
->m_x
+ child
->m_height
;
1296 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1298 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1300 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1302 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1305 event
.m_x
-= child
->m_x
;
1306 event
.m_y
-= child
->m_y
;
1313 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1314 (child
->m_x
<= event
.m_x
) &&
1315 (child
->m_y
<= event
.m_y
) &&
1316 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1317 (child
->m_y
+child
->m_height
>= event
.m_y
))
1320 event
.m_x
-= child
->m_x
;
1321 event
.m_y
-= child
->m_y
;
1325 node
= node
->Next();
1329 event
.SetEventObject( win
);
1331 if (win
->GetEventHandler()->ProcessEvent( event
))
1333 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1340 //-----------------------------------------------------------------------------
1342 //-----------------------------------------------------------------------------
1344 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1347 wxapp_install_idle_handler();
1349 if (!win
->m_hasVMT
) return FALSE
;
1350 if (g_blockEventsOnDrag
) return FALSE
;
1352 g_focusWindow
= win
;
1354 if (win
->m_wxwindow
)
1356 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1358 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1360 printf( "SetFocus flag from " );
1361 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1362 printf( win->GetClassInfo()->GetClassName() );
1370 printf( "OnSetFocus from " );
1371 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1372 printf( win->GetClassInfo()->GetClassName() );
1374 printf( WXSTRINGCAST win->GetLabel() );
1378 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1379 event
.SetEventObject( win
);
1381 if (win
->GetEventHandler()->ProcessEvent( event
))
1383 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1390 //-----------------------------------------------------------------------------
1391 // "focus_out_event"
1392 //-----------------------------------------------------------------------------
1394 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1397 wxapp_install_idle_handler();
1399 if (!win
->m_hasVMT
) return FALSE
;
1400 if (g_blockEventsOnDrag
) return FALSE
;
1402 if (win
->m_wxwindow
)
1404 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1405 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1409 printf( "OnKillFocus from " );
1410 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1411 printf( win->GetClassInfo()->GetClassName() );
1415 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1416 event
.SetEventObject( win
);
1418 if (win
->GetEventHandler()->ProcessEvent( event
))
1420 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1427 //-----------------------------------------------------------------------------
1428 // "enter_notify_event"
1429 //-----------------------------------------------------------------------------
1431 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1434 wxapp_install_idle_handler();
1436 if (!win
->m_hasVMT
) return FALSE
;
1437 if (g_blockEventsOnDrag
) return FALSE
;
1439 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1441 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1442 #if (GTK_MINOR_VERSION > 0)
1443 event
.SetTimestamp( gdk_event
->time
);
1445 event
.SetEventObject( win
);
1449 GdkModifierType state
= (GdkModifierType
)0;
1451 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1453 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1454 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1455 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1456 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1457 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1458 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1459 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1461 event
.m_x
= (long)x
;
1462 event
.m_y
= (long)y
;
1464 if (win
->GetEventHandler()->ProcessEvent( event
))
1466 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1473 //-----------------------------------------------------------------------------
1474 // "leave_notify_event"
1475 //-----------------------------------------------------------------------------
1477 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1480 wxapp_install_idle_handler();
1482 if (!win
->m_hasVMT
) return FALSE
;
1483 if (g_blockEventsOnDrag
) return FALSE
;
1485 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1487 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1488 #if (GTK_MINOR_VERSION > 0)
1489 event
.SetTimestamp( gdk_event
->time
);
1491 event
.SetEventObject( win
);
1495 GdkModifierType state
= (GdkModifierType
)0;
1497 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1499 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1500 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1501 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1502 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1503 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1504 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1505 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1507 event
.m_x
= (long)x
;
1508 event
.m_y
= (long)y
;
1510 if (win
->GetEventHandler()->ProcessEvent( event
))
1512 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1519 //-----------------------------------------------------------------------------
1520 // "value_changed" from m_vAdjust
1521 //-----------------------------------------------------------------------------
1523 static void gtk_window_vscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1526 wxapp_install_idle_handler();
1528 if (g_blockEventsOnDrag
) return;
1530 if (!win
->m_hasVMT
) return;
1532 float diff
= adjust
->value
- win
->m_oldVerticalPos
;
1533 if (fabs(diff
) < 0.2) return;
1535 win
->m_oldVerticalPos
= adjust
->value
;
1537 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1538 GtkRange
*range
= GTK_RANGE( scrolledWindow
->vscrollbar
);
1540 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1541 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1542 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1543 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1544 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1546 // if (fabs(adjust->value-adjust->lower) < 0.2) command = wxEVT_SCROLLWIN_BOTTOM;
1547 // if (fabs(adjust->value-adjust->upper) < 0.2) command = wxEVT_SCROLLWIN_TOP;
1549 int value
= (int)(adjust
->value
+0.5);
1551 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1552 event
.SetEventObject( win
);
1553 win
->GetEventHandler()->ProcessEvent( event
);
1556 //-----------------------------------------------------------------------------
1557 // "value_changed" from m_hAdjust
1558 //-----------------------------------------------------------------------------
1560 static void gtk_window_hscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1563 wxapp_install_idle_handler();
1565 if (g_blockEventsOnDrag
) return;
1566 if (!win
->m_hasVMT
) return;
1568 float diff
= adjust
->value
- win
->m_oldHorizontalPos
;
1569 if (fabs(diff
) < 0.2) return;
1571 win
->m_oldHorizontalPos
= adjust
->value
;
1573 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1574 GtkRange
*range
= GTK_RANGE( scrolledWindow
->hscrollbar
);
1576 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1577 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1578 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1579 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1580 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1582 // if (fabs(adjust->value-adjust->lower) < 0.2) command = wxEVT_SCROLLWIN_BOTTOM;
1583 // if (fabs(adjust->value-adjust->upper) < 0.2) command = wxEVT_SCROLLWIN_TOP;
1585 int value
= (int)(adjust
->value
+0.5);
1587 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1588 event
.SetEventObject( win
);
1589 win
->GetEventHandler()->ProcessEvent( event
);
1592 //-----------------------------------------------------------------------------
1593 // "changed" from m_vAdjust
1594 //-----------------------------------------------------------------------------
1596 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1599 wxapp_install_idle_handler();
1601 if (g_blockEventsOnDrag
) return;
1602 if (!win
->m_hasVMT
) return;
1604 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1605 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1607 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1608 event
.SetEventObject( win
);
1609 win
->GetEventHandler()->ProcessEvent( event
);
1612 //-----------------------------------------------------------------------------
1613 // "changed" from m_hAdjust
1614 //-----------------------------------------------------------------------------
1616 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1619 wxapp_install_idle_handler();
1621 if (g_blockEventsOnDrag
) return;
1622 if (!win
->m_hasVMT
) return;
1624 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1625 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1627 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1628 event
.SetEventObject( win
);
1629 win
->GetEventHandler()->ProcessEvent( event
);
1632 //-----------------------------------------------------------------------------
1633 // "button_press_event" from scrollbar
1634 //-----------------------------------------------------------------------------
1636 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1637 GdkEventButton
*WXUNUSED(gdk_event
),
1641 wxapp_install_idle_handler();
1643 // don't test here as we can release the mouse while being over
1644 // a different window than the slider
1646 // if (gdk_event->window != widget->slider) return FALSE;
1648 win
->SetScrolling( TRUE
);
1653 //-----------------------------------------------------------------------------
1654 // "button_release_event" from scrollbar
1655 //-----------------------------------------------------------------------------
1657 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1658 GdkEventButton
*WXUNUSED(gdk_event
),
1662 // don't test here as we can release the mouse while being over
1663 // a different window than the slider
1665 // if (gdk_event->window != widget->slider) return FALSE;
1667 // GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
1669 // if (widget == GTK_RANGE(scrolledWindow->vscrollbar))
1670 // gtk_signal_emit_by_name( GTK_OBJECT(win->m_hAdjust), "value_changed" );
1672 // gtk_signal_emit_by_name( GTK_OBJECT(win->m_vAdjust), "value_changed" );
1674 win
->SetScrolling( FALSE
);
1679 // ----------------------------------------------------------------------------
1680 // this wxWindowBase function is implemented here (in platform-specific file)
1681 // because it is static and so couldn't be made virtual
1682 // ----------------------------------------------------------------------------
1684 wxWindow
*wxWindowBase::FindFocus()
1686 return g_focusWindow
;
1689 //-----------------------------------------------------------------------------
1690 // "realize" from m_widget
1691 //-----------------------------------------------------------------------------
1693 /* we cannot set colours and fonts before the widget has
1694 been realized, so we do this directly after realization */
1697 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1700 wxapp_install_idle_handler();
1702 if (win
->m_delayedFont
)
1703 win
->SetFont( win
->GetFont() );
1705 if (win
->m_delayedBackgroundColour
)
1706 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1708 if (win
->m_delayedForegroundColour
)
1709 win
->SetForegroundColour( win
->GetForegroundColour() );
1711 wxWindowCreateEvent
event( win
);
1712 event
.SetEventObject( win
);
1713 win
->GetEventHandler()->ProcessEvent( event
);
1718 //-----------------------------------------------------------------------------
1719 // InsertChild for wxWindow.
1720 //-----------------------------------------------------------------------------
1722 /* Callback for wxWindow. This very strange beast has to be used because
1723 * C++ has no virtual methods in a constructor. We have to emulate a
1724 * virtual function here as wxNotebook requires a different way to insert
1725 * a child in it. I had opted for creating a wxNotebookPage window class
1726 * which would have made this superfluous (such in the MDI window system),
1727 * but no-one was listening to me... */
1729 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1731 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1732 GTK_WIDGET(child
->m_widget
),
1738 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1740 /* we now allow a window to get the focus as long as it
1741 doesn't have any children. */
1742 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1746 //-----------------------------------------------------------------------------
1748 //-----------------------------------------------------------------------------
1750 wxWindow
* wxGetActiveWindow()
1752 return g_focusWindow
;
1755 //-----------------------------------------------------------------------------
1757 //-----------------------------------------------------------------------------
1759 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1761 void wxWindow::Init()
1767 m_widget
= (GtkWidget
*) NULL
;
1768 m_wxwindow
= (GtkWidget
*) NULL
;
1778 m_needParent
= TRUE
;
1779 m_isBeingDeleted
= FALSE
;
1781 m_hasScrolling
= FALSE
;
1782 m_isScrolling
= FALSE
;
1784 m_hAdjust
= (GtkAdjustment
*) NULL
;
1785 m_vAdjust
= (GtkAdjustment
*) NULL
;
1786 m_oldHorizontalPos
= 0.0;
1787 m_oldVerticalPos
= 0.0;
1790 m_scrollGC
= (GdkGC
*) NULL
;
1791 m_widgetStyle
= (GtkStyle
*) NULL
;
1793 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1795 m_isStaticBox
= FALSE
;
1796 m_isRadioButton
= FALSE
;
1797 m_acceptsFocus
= FALSE
;
1799 m_cursor
= *wxSTANDARD_CURSOR
;
1802 wxWindow::wxWindow()
1807 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1808 const wxPoint
&pos
, const wxSize
&size
,
1809 long style
, const wxString
&name
)
1813 Create( parent
, id
, pos
, size
, style
, name
);
1816 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1817 const wxPoint
&pos
, const wxSize
&size
,
1818 long style
, const wxString
&name
)
1820 if (!PreCreation( parent
, pos
, size
) ||
1821 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
1823 wxFAIL_MSG( _T("wxWindow creation failed") );
1827 m_insertCallback
= wxInsertChildInWindow
;
1829 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1830 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1833 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1836 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1839 debug_focus_in( scrolledWindow
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1840 debug_focus_in( scrolledWindow
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1843 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1844 scroll_class
->scrollbar_spacing
= 0;
1846 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1848 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1849 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1851 m_wxwindow
= gtk_myfixed_new();
1854 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1857 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1859 #if (GTK_MINOR_VERSION > 0)
1860 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1862 if (HasFlag(wxRAISED_BORDER
))
1864 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_OUT
);
1866 else if (HasFlag(wxSUNKEN_BORDER
))
1868 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_IN
);
1870 else if (HasFlag(wxSIMPLE_BORDER
))
1872 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_THIN
);
1876 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_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", "raised" or "simple" 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
;
2231 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2232 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2238 GdkWindow
*window
= m_widget
->window
;
2239 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2240 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2248 void wxWindow::DoGetSize( int *width
, int *height
) const
2250 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2252 if (width
) (*width
) = m_width
;
2253 if (height
) (*height
) = m_height
;
2256 void wxWindow::DoSetClientSize( int width
, int height
)
2258 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2262 SetSize( width
, height
);
2269 #if (GTK_MINOR_VERSION == 0)
2270 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2274 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2275 #if 0 // unused - if this is ok, just remove this line (VZ)
2276 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2279 GtkWidget
*viewport
= scroll_window
->viewport
;
2280 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2282 dw
+= 2 * viewport_class
->xthickness
;
2283 dh
+= 2 * viewport_class
->ythickness
;
2287 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2289 /* when using GTK 1.2 we set the shadow border size to 2 */
2293 if (HasFlag(wxSIMPLE_BORDER
))
2295 /* when using GTK 1.2 we set the simple border size to 1 */
2304 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2305 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2307 we use this instead: range.slider_width = 11 + 2*2pts edge
2310 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2311 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2313 if (scroll_window
->vscrollbar_visible
)
2315 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2316 dw
+= scroll_class
->scrollbar_spacing
;
2319 if (scroll_window
->hscrollbar_visible
)
2321 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2322 dh
+= scroll_class
->scrollbar_spacing
;
2326 SetSize( width
+dw
, height
+dh
);
2330 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2332 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2336 if (width
) (*width
) = m_width
;
2337 if (height
) (*height
) = m_height
;
2344 #if (GTK_MINOR_VERSION == 0)
2345 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2349 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2350 #if 0 // unused - if this is ok, just remove this line (VZ)
2351 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2354 GtkWidget
*viewport
= scroll_window
->viewport
;
2355 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2357 dw
+= 2 * viewport_class
->xthickness
;
2358 dh
+= 2 * viewport_class
->ythickness
;
2362 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2364 /* when using GTK 1.2 we set the shadow border size to 2 */
2368 if (HasFlag(wxSIMPLE_BORDER
))
2370 /* when using GTK 1.2 we set the simple border size to 1 */
2378 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2379 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2381 we use this instead: range.slider_width = 11 + 2*2pts edge
2384 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2385 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2387 if (scroll_window
->vscrollbar_visible
)
2389 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2390 dw
+= scroll_class
->scrollbar_spacing
;
2393 if (scroll_window
->hscrollbar_visible
)
2395 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2396 dh
+= scroll_class
->scrollbar_spacing
;
2400 if (width
) (*width
) = m_width
- dw
;
2401 if (height
) (*height
) = m_height
- dh
;
2405 void wxWindow::DoGetPosition( int *x
, int *y
) const
2407 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2413 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2415 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2417 if (!m_widget
->window
) return;
2419 GdkWindow
*source
= (GdkWindow
*) NULL
;
2421 source
= m_wxwindow
->window
;
2423 source
= m_widget
->window
;
2427 gdk_window_get_origin( source
, &org_x
, &org_y
);
2431 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2433 org_x
+= m_widget
->allocation
.x
;
2434 org_y
+= m_widget
->allocation
.y
;
2442 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2444 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2446 if (!m_widget
->window
) return;
2448 GdkWindow
*source
= (GdkWindow
*) NULL
;
2450 source
= m_wxwindow
->window
;
2452 source
= m_widget
->window
;
2456 gdk_window_get_origin( source
, &org_x
, &org_y
);
2460 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2462 org_x
+= m_widget
->allocation
.x
;
2463 org_y
+= m_widget
->allocation
.y
;
2471 bool wxWindow::Show( bool show
)
2473 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2475 if (!wxWindowBase::Show(show
))
2482 gtk_widget_show( m_widget
);
2484 gtk_widget_hide( m_widget
);
2489 bool wxWindow::Enable( bool enable
)
2491 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2493 if (!wxWindowBase::Enable(enable
))
2499 gtk_widget_set_sensitive( m_widget
, enable
);
2501 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2506 int wxWindow::GetCharHeight() const
2508 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2510 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2512 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2514 return font
->ascent
+ font
->descent
;
2517 int wxWindow::GetCharWidth() const
2519 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2521 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2523 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2525 return gdk_string_width( font
, "H" );
2528 void wxWindow::GetTextExtent( const wxString
& string
,
2532 int *externalLeading
,
2533 const wxFont
*theFont
) const
2535 wxFont fontToUse
= m_font
;
2536 if (theFont
) fontToUse
= *theFont
;
2538 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2540 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2541 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2542 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2543 if (descent
) (*descent
) = font
->descent
;
2544 if (externalLeading
) (*externalLeading
) = 0; // ??
2547 void wxWindow::SetFocus()
2549 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2551 GtkWidget
*connect_widget
= GetConnectWidget();
2554 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2556 gtk_widget_grab_focus (connect_widget
);
2558 else if (GTK_IS_CONTAINER(connect_widget
))
2560 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2568 bool wxWindow::AcceptsFocus() const
2570 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2573 bool wxWindow::Reparent( wxWindowBase
*newParentBase
)
2575 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2577 wxWindow
*oldParent
= m_parent
,
2578 *newParent
= (wxWindow
*)newParentBase
;
2580 if ( !wxWindowBase::Reparent(newParent
) )
2585 gtk_container_remove( GTK_CONTAINER(oldParent
->m_wxwindow
), m_widget
);
2590 /* insert GTK representation */
2591 (*(newParent
->m_insertCallback
))(newParent
, this);
2597 void wxWindow::DoAddChild(wxWindow
*child
)
2599 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
2601 wxASSERT_MSG( (child
!= NULL
), _T("invalid child window") );
2603 wxASSERT_MSG( (m_insertCallback
!= NULL
), _T("invalid child insertion function") );
2608 /* insert GTK representation */
2609 (*m_insertCallback
)(this, child
);
2612 void wxWindow::Raise()
2614 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2616 if (!m_widget
->window
) return;
2618 gdk_window_raise( m_widget
->window
);
2621 void wxWindow::Lower()
2623 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2625 if (!m_widget
->window
) return;
2627 gdk_window_lower( m_widget
->window
);
2630 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2632 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2634 return wxWindowBase::SetCursor( cursor
);
2637 void wxWindow::WarpPointer( int x
, int y
)
2639 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2641 GtkWidget
*connect_widget
= GetConnectWidget();
2642 if (connect_widget
->window
)
2644 /* we provide this function ourselves as it is
2646 gdk_window_warp_pointer( connect_widget
->window
, x
, y
);
2650 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2652 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2654 if (!m_widget
->window
) return;
2656 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2660 gdk_window_clear_area( m_wxwindow
->window
,
2662 rect
->width
, rect
->height
);
2666 gdk_window_clear( m_wxwindow
->window
);
2673 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2675 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2679 GdkRectangle gdk_rect
;
2680 gdk_rect
.x
= rect
->x
;
2681 gdk_rect
.y
= rect
->y
;
2682 gdk_rect
.width
= rect
->width
;
2683 gdk_rect
.height
= rect
->height
;
2686 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2688 gtk_widget_draw( m_widget
, &gdk_rect
);
2692 void wxWindow::Clear()
2694 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2696 if (!m_widget
->window
) return;
2698 if (m_wxwindow
&& m_wxwindow
->window
)
2700 gdk_window_clear( m_wxwindow
->window
);
2705 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2707 wxWindowBase::DoSetToolTip(tip
);
2710 m_tooltip
->Apply( this );
2713 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2715 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2717 #endif // wxUSE_TOOLTIPS
2719 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2721 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2723 if (!wxWindowBase::SetBackgroundColour(colour
))
2725 // don't leave if the GTK widget has just
2727 if (!m_delayedBackgroundColour
) return FALSE
;
2730 GtkWidget
*connect_widget
= GetConnectWidget();
2731 if (!connect_widget
->window
)
2733 // indicate that a new style has been set
2734 // but it couldn't get applied as the
2735 // widget hasn't been realized yet.
2736 m_delayedBackgroundColour
= TRUE
;
2738 // pretend we have done something
2742 if (m_wxwindow
&& m_wxwindow
->window
)
2744 /* wxMSW doesn't clear the window here. I don't do that either to
2745 provide compatibility. call Clear() to do the job. */
2747 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2748 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2751 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2752 if (sysbg
== m_backgroundColour
)
2754 m_backgroundColour
= wxNullColour
;
2756 m_backgroundColour
= sysbg
;
2766 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2768 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2770 if (!wxWindowBase::SetForegroundColour(colour
))
2772 // don't leave if the GTK widget has just
2774 if (!m_delayedForegroundColour
) return FALSE
;
2777 GtkWidget
*connect_widget
= GetConnectWidget();
2778 if (!connect_widget
->window
)
2780 // indicate that a new style has been set
2781 // but it couldn't get applied as the
2782 // widget hasn't been realized yet.
2783 m_delayedForegroundColour
= TRUE
;
2785 // pretend we have done something
2789 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2790 if ( sysbg
== m_backgroundColour
)
2792 m_backgroundColour
= wxNullColour
;
2794 m_backgroundColour
= sysbg
;
2804 GtkStyle
*wxWindow::GetWidgetStyle()
2806 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2808 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2810 return m_widgetStyle
;
2813 void wxWindow::SetWidgetStyle()
2815 GtkStyle
*style
= GetWidgetStyle();
2817 gdk_font_unref( style
->font
);
2818 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2820 if (m_foregroundColour
.Ok())
2822 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2823 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2824 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2825 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2828 if (m_backgroundColour
.Ok())
2830 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2831 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2832 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2833 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2834 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2835 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2836 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2837 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2838 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2842 void wxWindow::ApplyWidgetStyle()
2846 //-----------------------------------------------------------------------------
2847 // Pop-up menu stuff
2848 //-----------------------------------------------------------------------------
2850 static void gtk_pop_hide_callback( GtkWidget
*WXUNUSED(widget
), bool* is_waiting
)
2852 *is_waiting
= FALSE
;
2855 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2857 menu
->SetInvokingWindow( win
);
2858 wxNode
*node
= menu
->GetItems().First();
2861 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2862 if (menuitem
->IsSubMenu())
2864 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2866 node
= node
->Next();
2870 static gint gs_pop_x
= 0;
2871 static gint gs_pop_y
= 0;
2873 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2877 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2882 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
2884 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2886 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2888 SetInvokingWindow( menu
, this );
2895 bool is_waiting
= TRUE
;
2897 gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide",
2898 GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting
);
2901 GTK_MENU(menu
->m_menu
),
2902 (GtkWidget
*) NULL
, // parent menu shell
2903 (GtkWidget
*) NULL
, // parent menu item
2904 (GtkMenuPositionFunc
) pop_pos_callback
,
2905 (gpointer
) this, // client data
2906 0, // button used to activate it
2907 0 //gs_timeLastClick // the time of activation
2912 while (gtk_events_pending())
2913 gtk_main_iteration();
2919 #if wxUSE_DRAG_AND_DROP
2921 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2923 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2925 GtkWidget
*dnd_widget
= GetConnectWidget();
2927 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2929 if (m_dropTarget
) delete m_dropTarget
;
2930 m_dropTarget
= dropTarget
;
2932 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2935 #endif // wxUSE_DRAG_AND_DROP
2937 GtkWidget
* wxWindow::GetConnectWidget()
2939 GtkWidget
*connect_widget
= m_widget
;
2940 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2942 return connect_widget
;
2945 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2947 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2948 return (window
== m_widget
->window
);
2951 bool wxWindow::SetFont( const wxFont
&font
)
2953 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2955 if (!wxWindowBase::SetFont(font
))
2957 // don't leave if the GTK widget has just
2959 if (!m_delayedFont
) return FALSE
;
2962 GtkWidget
*connect_widget
= GetConnectWidget();
2963 if (!connect_widget
->window
)
2965 // indicate that a new style has been set
2966 // but it couldn't get applied as the
2967 // widget hasn't been realized yet.
2968 m_delayedFont
= TRUE
;
2970 // pretend we have done something
2974 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2975 if ( sysbg
== m_backgroundColour
)
2977 m_backgroundColour
= wxNullColour
;
2979 m_backgroundColour
= sysbg
;
2989 void wxWindow::CaptureMouse()
2991 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2993 wxCHECK_RET( g_captureWindow
== NULL
, _T("CaptureMouse called twice") );
2995 GtkWidget
*connect_widget
= GetConnectWidget();
2996 if (!connect_widget
->window
) return;
2998 gdk_pointer_grab( connect_widget
->window
, FALSE
,
3000 (GDK_BUTTON_PRESS_MASK
|
3001 GDK_BUTTON_RELEASE_MASK
|
3002 GDK_POINTER_MOTION_MASK
),
3004 m_cursor
.GetCursor(),
3006 g_captureWindow
= this;
3009 void wxWindow::ReleaseMouse()
3011 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3013 wxCHECK_RET( g_captureWindow
, _T("ReleaseMouse called twice") );
3015 GtkWidget
*connect_widget
= GetConnectWidget();
3016 if (!connect_widget
->window
) return;
3018 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3019 g_captureWindow
= (wxWindow
*) NULL
;
3022 bool wxWindow::IsRetained() const
3027 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3028 int range
, bool refresh
)
3030 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3032 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3034 m_hasScrolling
= TRUE
;
3036 if (orient
== wxHORIZONTAL
)
3038 float fpos
= (float)pos
;
3039 float frange
= (float)range
;
3040 float fthumb
= (float)thumbVisible
;
3041 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3042 if (fpos
< 0.0) fpos
= 0.0;
3044 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3045 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3047 SetScrollPos( orient
, pos
, refresh
);
3051 m_oldHorizontalPos
= fpos
;
3053 m_hAdjust
->lower
= 0.0;
3054 m_hAdjust
->upper
= frange
;
3055 m_hAdjust
->value
= fpos
;
3056 m_hAdjust
->step_increment
= 1.0;
3057 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3058 m_hAdjust
->page_size
= fthumb
;
3062 float fpos
= (float)pos
;
3063 float frange
= (float)range
;
3064 float fthumb
= (float)thumbVisible
;
3065 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3066 if (fpos
< 0.0) fpos
= 0.0;
3068 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3069 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3071 SetScrollPos( orient
, pos
, refresh
);
3075 m_oldVerticalPos
= fpos
;
3077 m_vAdjust
->lower
= 0.0;
3078 m_vAdjust
->upper
= frange
;
3079 m_vAdjust
->value
= fpos
;
3080 m_vAdjust
->step_increment
= 1.0;
3081 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3082 m_vAdjust
->page_size
= fthumb
;
3085 if (orient
== wxHORIZONTAL
)
3086 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3088 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3091 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3093 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3095 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3097 if (orient
== wxHORIZONTAL
)
3099 float fpos
= (float)pos
;
3100 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3101 if (fpos
< 0.0) fpos
= 0.0;
3102 m_oldHorizontalPos
= fpos
;
3104 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3105 m_hAdjust
->value
= fpos
;
3109 float fpos
= (float)pos
;
3110 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3111 if (fpos
< 0.0) fpos
= 0.0;
3112 m_oldVerticalPos
= fpos
;
3114 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3115 m_vAdjust
->value
= fpos
;
3122 if (m_wxwindow
->window
)
3124 if (orient
== wxHORIZONTAL
)
3125 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3127 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3134 int wxWindow::GetScrollThumb( int orient
) const
3136 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3138 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3140 if (orient
== wxHORIZONTAL
)
3141 return (int)(m_hAdjust
->page_size
+0.5);
3143 return (int)(m_vAdjust
->page_size
+0.5);
3146 int wxWindow::GetScrollPos( int orient
) const
3148 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3150 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3152 if (orient
== wxHORIZONTAL
)
3153 return (int)(m_hAdjust
->value
+0.5);
3155 return (int)(m_vAdjust
->value
+0.5);
3158 int wxWindow::GetScrollRange( int orient
) const
3160 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3162 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3164 if (orient
== wxHORIZONTAL
)
3165 return (int)(m_hAdjust
->upper
+0.5);
3167 return (int)(m_vAdjust
->upper
+0.5);
3170 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3172 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3174 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3178 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3179 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3182 wxNode
*node
= m_children
.First();
3185 wxWindow
*child
= (wxWindow
*) node
->Data();
3188 child
->GetSize( &sx
, &sy
);
3189 child
->SetSize( child
->m_x
+ dx
, child
->m_y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
3190 node
= node
->Next();
3195 GetClientSize( &cw
, &ch
);
3196 int w
= cw
- abs(dx
);
3197 int h
= ch
- abs(dy
);
3199 if ((h
< 0) || (w
< 0))
3207 if (dx
< 0) s_x
= -dx
;
3208 if (dy
< 0) s_y
= -dy
;
3211 if (dx
> 0) d_x
= dx
;
3212 if (dy
> 0) d_y
= dy
;
3214 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3215 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3218 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3219 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3220 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3221 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3223 Refresh( TRUE
, &rect
);
3227 void wxWindow::SetScrolling(bool scroll
)
3229 m_isScrolling
= g_blockEventsOnScroll
= scroll
;