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(wxT("FOCUS NOW AT: %s"), name);
164 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
167 tmp
+= wxT(" FROM ");
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 // local code (see below)
215 //-----------------------------------------------------------------------------
217 #if (GTK_MINOR_VERSION > 0)
219 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
227 if (win
->HasScrolling())
229 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
230 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
233 GtkWidget *hscrollbar = scroll_window->hscrollbar;
234 GtkWidget *vscrollbar = scroll_window->vscrollbar;
236 we use this instead: range.slider_width = 11 + 2*2pts edge
239 if (scroll_window
->vscrollbar_visible
)
241 dw
+= 15; /* dw += vscrollbar->allocation.width; */
242 dw
+= scroll_class
->scrollbar_spacing
;
245 if (scroll_window
->hscrollbar_visible
)
247 dh
+= 15; /* dh += hscrollbar->allocation.height; */
248 dh
+= scroll_class
->scrollbar_spacing
;
254 if (GTK_WIDGET_NO_WINDOW (widget
))
256 dx
+= widget
->allocation
.x
;
257 dy
+= widget
->allocation
.y
;
260 if (win
->HasFlag(wxRAISED_BORDER
))
262 gtk_draw_shadow( widget
->style
,
267 win
->m_width
-dw
, win
->m_height
-dh
);
271 if (win
->HasFlag(wxSUNKEN_BORDER
))
273 gtk_draw_shadow( widget
->style
,
278 win
->m_width
-dw
, win
->m_height
-dh
);
282 if (win
->HasFlag(wxSIMPLE_BORDER
))
285 gc
= gdk_gc_new( widget
->window
);
286 gdk_gc_set_foreground( gc
, &widget
->style
->black
);
287 gdk_draw_rectangle( widget
->window
, gc
, FALSE
,
289 win
->m_width
-dw
-1, win
->m_height
-dh
-1 );
295 //-----------------------------------------------------------------------------
296 // "expose_event" of m_widget
297 //-----------------------------------------------------------------------------
299 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
301 if (gdk_event
->count
> 0) return;
302 draw_frame( widget
, win
);
305 //-----------------------------------------------------------------------------
306 // "draw" of m_widget
307 //-----------------------------------------------------------------------------
309 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
311 draw_frame( widget
, win
);
314 #endif // GTK_MINOR_VERSION > 0
316 //-----------------------------------------------------------------------------
317 // key event conversion routines
318 //-----------------------------------------------------------------------------
320 #if (GTK_MINOR_VERSION == 0)
321 /* these functions are copied verbatim from GTK 1.2 */
323 gdkx_XConvertCase (KeySym symbol
,
327 register KeySym sym
= symbol
;
329 g_return_if_fail (lower
!= NULL
);
330 g_return_if_fail (upper
!= NULL
);
337 #if defined (GDK_A) && defined (GDK_Ooblique)
338 case 0: /* Latin 1 */
339 if ((sym
>= GDK_A
) && (sym
<= GDK_Z
))
340 *lower
+= (GDK_a
- GDK_A
);
341 else if ((sym
>= GDK_a
) && (sym
<= GDK_z
))
342 *upper
-= (GDK_a
- GDK_A
);
343 else if ((sym
>= GDK_Agrave
) && (sym
<= GDK_Odiaeresis
))
344 *lower
+= (GDK_agrave
- GDK_Agrave
);
345 else if ((sym
>= GDK_agrave
) && (sym
<= GDK_odiaeresis
))
346 *upper
-= (GDK_agrave
- GDK_Agrave
);
347 else if ((sym
>= GDK_Ooblique
) && (sym
<= GDK_Thorn
))
348 *lower
+= (GDK_oslash
- GDK_Ooblique
);
349 else if ((sym
>= GDK_oslash
) && (sym
<= GDK_thorn
))
350 *upper
-= (GDK_oslash
- GDK_Ooblique
);
354 #if defined (GDK_Aogonek) && defined (GDK_tcedilla)
355 case 1: /* Latin 2 */
356 /* Assume the KeySym is a legal value (ignore discontinuities) */
357 if (sym
== GDK_Aogonek
)
358 *lower
= GDK_aogonek
;
359 else if (sym
>= GDK_Lstroke
&& sym
<= GDK_Sacute
)
360 *lower
+= (GDK_lstroke
- GDK_Lstroke
);
361 else if (sym
>= GDK_Scaron
&& sym
<= GDK_Zacute
)
362 *lower
+= (GDK_scaron
- GDK_Scaron
);
363 else if (sym
>= GDK_Zcaron
&& sym
<= GDK_Zabovedot
)
364 *lower
+= (GDK_zcaron
- GDK_Zcaron
);
365 else if (sym
== GDK_aogonek
)
366 *upper
= GDK_Aogonek
;
367 else if (sym
>= GDK_lstroke
&& sym
<= GDK_sacute
)
368 *upper
-= (GDK_lstroke
- GDK_Lstroke
);
369 else if (sym
>= GDK_scaron
&& sym
<= GDK_zacute
)
370 *upper
-= (GDK_scaron
- GDK_Scaron
);
371 else if (sym
>= GDK_zcaron
&& sym
<= GDK_zabovedot
)
372 *upper
-= (GDK_zcaron
- GDK_Zcaron
);
373 else if (sym
>= GDK_Racute
&& sym
<= GDK_Tcedilla
)
374 *lower
+= (GDK_racute
- GDK_Racute
);
375 else if (sym
>= GDK_racute
&& sym
<= GDK_tcedilla
)
376 *upper
-= (GDK_racute
- GDK_Racute
);
380 #if defined (GDK_Hstroke) && defined (GDK_Cabovedot)
381 case 2: /* Latin 3 */
382 /* Assume the KeySym is a legal value (ignore discontinuities) */
383 if (sym
>= GDK_Hstroke
&& sym
<= GDK_Hcircumflex
)
384 *lower
+= (GDK_hstroke
- GDK_Hstroke
);
385 else if (sym
>= GDK_Gbreve
&& sym
<= GDK_Jcircumflex
)
386 *lower
+= (GDK_gbreve
- GDK_Gbreve
);
387 else if (sym
>= GDK_hstroke
&& sym
<= GDK_hcircumflex
)
388 *upper
-= (GDK_hstroke
- GDK_Hstroke
);
389 else if (sym
>= GDK_gbreve
&& sym
<= GDK_jcircumflex
)
390 *upper
-= (GDK_gbreve
- GDK_Gbreve
);
391 else if (sym
>= GDK_Cabovedot
&& sym
<= GDK_Scircumflex
)
392 *lower
+= (GDK_cabovedot
- GDK_Cabovedot
);
393 else if (sym
>= GDK_cabovedot
&& sym
<= GDK_scircumflex
)
394 *upper
-= (GDK_cabovedot
- GDK_Cabovedot
);
398 #if defined (GDK_Rcedilla) && defined (GDK_Amacron)
399 case 3: /* Latin 4 */
400 /* Assume the KeySym is a legal value (ignore discontinuities) */
401 if (sym
>= GDK_Rcedilla
&& sym
<= GDK_Tslash
)
402 *lower
+= (GDK_rcedilla
- GDK_Rcedilla
);
403 else if (sym
>= GDK_rcedilla
&& sym
<= GDK_tslash
)
404 *upper
-= (GDK_rcedilla
- GDK_Rcedilla
);
405 else if (sym
== GDK_ENG
)
407 else if (sym
== GDK_eng
)
409 else if (sym
>= GDK_Amacron
&& sym
<= GDK_Umacron
)
410 *lower
+= (GDK_amacron
- GDK_Amacron
);
411 else if (sym
>= GDK_amacron
&& sym
<= GDK_umacron
)
412 *upper
-= (GDK_amacron
- GDK_Amacron
);
416 #if defined (GDK_Serbian_DJE) && defined (GDK_Cyrillic_yu)
417 case 6: /* Cyrillic */
418 /* Assume the KeySym is a legal value (ignore discontinuities) */
419 if (sym
>= GDK_Serbian_DJE
&& sym
<= GDK_Serbian_DZE
)
420 *lower
-= (GDK_Serbian_DJE
- GDK_Serbian_dje
);
421 else if (sym
>= GDK_Serbian_dje
&& sym
<= GDK_Serbian_dze
)
422 *upper
+= (GDK_Serbian_DJE
- GDK_Serbian_dje
);
423 else if (sym
>= GDK_Cyrillic_YU
&& sym
<= GDK_Cyrillic_HARDSIGN
)
424 *lower
-= (GDK_Cyrillic_YU
- GDK_Cyrillic_yu
);
425 else if (sym
>= GDK_Cyrillic_yu
&& sym
<= GDK_Cyrillic_hardsign
)
426 *upper
+= (GDK_Cyrillic_YU
- GDK_Cyrillic_yu
);
428 #endif /* CYRILLIC */
430 #if defined (GDK_Greek_ALPHAaccent) && defined (GDK_Greek_finalsmallsigma)
432 /* Assume the KeySym is a legal value (ignore discontinuities) */
433 if (sym
>= GDK_Greek_ALPHAaccent
&& sym
<= GDK_Greek_OMEGAaccent
)
434 *lower
+= (GDK_Greek_alphaaccent
- GDK_Greek_ALPHAaccent
);
435 else if (sym
>= GDK_Greek_alphaaccent
&& sym
<= GDK_Greek_omegaaccent
&&
436 sym
!= GDK_Greek_iotaaccentdieresis
&&
437 sym
!= GDK_Greek_upsilonaccentdieresis
)
438 *upper
-= (GDK_Greek_alphaaccent
- GDK_Greek_ALPHAaccent
);
439 else if (sym
>= GDK_Greek_ALPHA
&& sym
<= GDK_Greek_OMEGA
)
440 *lower
+= (GDK_Greek_alpha
- GDK_Greek_ALPHA
);
441 else if (sym
>= GDK_Greek_alpha
&& sym
<= GDK_Greek_omega
&&
442 sym
!= GDK_Greek_finalsmallsigma
)
443 *upper
-= (GDK_Greek_alpha
- GDK_Greek_ALPHA
);
450 gdk_keyval_to_upper (guint keyval
)
454 KeySym lower_val
= 0;
455 KeySym upper_val
= 0;
457 gdkx_XConvertCase (keyval
, &lower_val
, &upper_val
);
464 static long map_to_unmodified_wx_keysym( KeySym keysym
)
471 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
473 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
479 case GDK_Super_R
: key_code
= WXK_ALT
; break;
480 case GDK_Menu
: key_code
= WXK_MENU
; break;
481 case GDK_Help
: key_code
= WXK_HELP
; break;
482 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
483 case GDK_ISO_Left_Tab
:
484 case GDK_Tab
: key_code
= WXK_TAB
; break;
485 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
486 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
487 case GDK_Return
: key_code
= WXK_RETURN
; break;
488 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
489 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
490 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
491 case GDK_Delete
: key_code
= WXK_DELETE
; break;
492 case GDK_Home
: key_code
= WXK_HOME
; break;
493 case GDK_Left
: key_code
= WXK_LEFT
; break;
494 case GDK_Up
: key_code
= WXK_UP
; break;
495 case GDK_Right
: key_code
= WXK_RIGHT
; break;
496 case GDK_Down
: key_code
= WXK_DOWN
; break;
497 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
498 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
499 case GDK_Next
: key_code
= WXK_NEXT
; break;
500 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
501 case GDK_End
: key_code
= WXK_END
; break;
502 case GDK_Begin
: key_code
= WXK_HOME
; break;
503 case GDK_Select
: key_code
= WXK_SELECT
; break;
504 case GDK_Print
: key_code
= WXK_PRINT
; break;
505 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
506 case GDK_Insert
: key_code
= WXK_INSERT
; break;
507 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
509 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
510 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
511 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
512 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
513 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
514 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
515 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
516 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
517 case GDK_KP_8
: key_code
= WXK_NUMPAD8
; break;
518 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
519 case GDK_KP_Space
: key_code
= WXK_NUMPAD_SPACE
; break;
520 case GDK_KP_Tab
: key_code
= WXK_NUMPAD_TAB
; break;
521 case GDK_KP_Enter
: key_code
= WXK_NUMPAD_ENTER
; break;
522 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
523 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
524 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
525 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
526 case GDK_KP_Home
: key_code
= WXK_NUMPAD_HOME
; break;
527 case GDK_KP_Left
: key_code
= WXK_NUMPAD_LEFT
; break;
528 case GDK_KP_Up
: key_code
= WXK_NUMPAD_UP
; break;
529 case GDK_KP_Right
: key_code
= WXK_NUMPAD_RIGHT
; break;
530 case GDK_KP_Down
: key_code
= WXK_NUMPAD_DOWN
; break;
531 case GDK_KP_Prior
: key_code
= WXK_NUMPAD_PRIOR
; break;
532 // case GDK_KP_Page_Up: key_code = WXK_NUMPAD_PAGEUP; break;
533 case GDK_KP_Next
: key_code
= WXK_NUMPAD_NEXT
; break;
534 // case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break;
535 case GDK_KP_End
: key_code
= WXK_NUMPAD_END
; break;
536 case GDK_KP_Begin
: key_code
= WXK_NUMPAD_BEGIN
; break;
537 case GDK_KP_Insert
: key_code
= WXK_NUMPAD_INSERT
; break;
538 case GDK_KP_Delete
: key_code
= WXK_NUMPAD_DELETE
; break;
539 case GDK_KP_Equal
: key_code
= WXK_NUMPAD_EQUAL
; break;
540 case GDK_KP_Multiply
: key_code
= WXK_NUMPAD_MULTIPLY
; break;
541 case GDK_KP_Add
: key_code
= WXK_NUMPAD_ADD
; break;
542 case GDK_KP_Separator
: key_code
= WXK_NUMPAD_SEPARATOR
; break;
543 case GDK_KP_Subtract
: key_code
= WXK_NUMPAD_SUBTRACT
; break;
544 case GDK_KP_Decimal
: key_code
= WXK_NUMPAD_DECIMAL
; break;
545 case GDK_KP_Divide
: key_code
= WXK_NUMPAD_DIVIDE
; break;
547 case GDK_F1
: key_code
= WXK_F1
; break;
548 case GDK_F2
: key_code
= WXK_F2
; break;
549 case GDK_F3
: key_code
= WXK_F3
; break;
550 case GDK_F4
: key_code
= WXK_F4
; break;
551 case GDK_F5
: key_code
= WXK_F5
; break;
552 case GDK_F6
: key_code
= WXK_F6
; break;
553 case GDK_F7
: key_code
= WXK_F7
; break;
554 case GDK_F8
: key_code
= WXK_F8
; break;
555 case GDK_F9
: key_code
= WXK_F9
; break;
556 case GDK_F10
: key_code
= WXK_F10
; break;
557 case GDK_F11
: key_code
= WXK_F11
; break;
558 case GDK_F12
: key_code
= WXK_F12
; break;
563 guint upper
= gdk_keyval_to_upper( keysym
);
564 keysym
= (upper
!= 0 ? upper
: keysym
); /* to be MSW compatible */
573 static long map_to_wx_keysym( KeySym keysym
)
579 case GDK_Menu
: key_code
= WXK_MENU
; break;
580 case GDK_Help
: key_code
= WXK_HELP
; break;
581 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
582 case GDK_ISO_Left_Tab
:
583 case GDK_Tab
: key_code
= WXK_TAB
; break;
584 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
585 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
586 case GDK_Return
: key_code
= WXK_RETURN
; break;
587 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
588 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
589 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
590 case GDK_Delete
: key_code
= WXK_DELETE
; break;
591 case GDK_Home
: key_code
= WXK_HOME
; break;
592 case GDK_Left
: key_code
= WXK_LEFT
; break;
593 case GDK_Up
: key_code
= WXK_UP
; break;
594 case GDK_Right
: key_code
= WXK_RIGHT
; break;
595 case GDK_Down
: key_code
= WXK_DOWN
; break;
596 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
597 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
598 case GDK_Next
: key_code
= WXK_NEXT
; break;
599 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
600 case GDK_End
: key_code
= WXK_END
; break;
601 case GDK_Begin
: key_code
= WXK_HOME
; break;
602 case GDK_Select
: key_code
= WXK_SELECT
; break;
603 case GDK_Print
: key_code
= WXK_PRINT
; break;
604 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
605 case GDK_Insert
: key_code
= WXK_INSERT
; break;
606 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
608 case GDK_KP_0
: key_code
= '0'; break;
609 case GDK_KP_1
: key_code
= '1'; break;
610 case GDK_KP_2
: key_code
= '2'; break;
611 case GDK_KP_3
: key_code
= '3'; break;
612 case GDK_KP_4
: key_code
= '4'; break;
613 case GDK_KP_5
: key_code
= '5'; break;
614 case GDK_KP_6
: key_code
= '6'; break;
615 case GDK_KP_7
: key_code
= '7'; break;
616 case GDK_KP_8
: key_code
= '8'; break;
617 case GDK_KP_9
: key_code
= '9'; break;
618 case GDK_KP_Space
: key_code
= ' '; break;
619 case GDK_KP_Tab
: key_code
= WXK_TAB
; break; /* or '\t' ??? */
620 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break; /* or '\r' ??? */
621 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
622 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
623 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
624 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
625 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
626 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
627 case GDK_KP_Up
: key_code
= WXK_UP
; break;
628 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
629 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
630 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
631 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
632 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
633 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
634 case GDK_KP_End
: key_code
= WXK_END
; break;
635 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
636 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
637 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
638 case GDK_KP_Equal
: key_code
= '='; break;
639 case GDK_KP_Multiply
: key_code
= '*'; break;
640 case GDK_KP_Add
: key_code
= '+'; break;
641 case GDK_KP_Separator
: key_code
= ','; break;
642 case GDK_KP_Subtract
: key_code
= '-'; break;
643 case GDK_KP_Decimal
: key_code
= '.'; break;
644 case GDK_KP_Divide
: key_code
= '/'; break;
646 case GDK_F1
: key_code
= WXK_F1
; break;
647 case GDK_F2
: key_code
= WXK_F2
; break;
648 case GDK_F3
: key_code
= WXK_F3
; break;
649 case GDK_F4
: key_code
= WXK_F4
; break;
650 case GDK_F5
: key_code
= WXK_F5
; break;
651 case GDK_F6
: key_code
= WXK_F6
; break;
652 case GDK_F7
: key_code
= WXK_F7
; break;
653 case GDK_F8
: key_code
= WXK_F8
; break;
654 case GDK_F9
: key_code
= WXK_F9
; break;
655 case GDK_F10
: key_code
= WXK_F10
; break;
656 case GDK_F11
: key_code
= WXK_F11
; break;
657 case GDK_F12
: key_code
= WXK_F12
; break;
670 //-----------------------------------------------------------------------------
671 // "expose_event" of m_wxwindow
672 //-----------------------------------------------------------------------------
674 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
679 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
681 gdk_event
->area
.width
,
682 gdk_event
->area
.height
);
684 if (gdk_event
->count
> 0)
688 wxPrintf( "OnExpose from " );
689 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
690 wxPrintf( win->GetClassInfo()->GetClassName() );
691 wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x,
692 (int)gdk_event->area.y,
693 (int)gdk_event->area.width,
694 (int)gdk_event->area.height );
697 wxEraseEvent
eevent( win
->GetId() );
698 eevent
.SetEventObject( win
);
699 win
->GetEventHandler()->ProcessEvent(eevent
);
701 wxPaintEvent
event( win
->GetId() );
702 event
.SetEventObject( win
);
703 win
->GetEventHandler()->ProcessEvent( event
);
705 win
->GetUpdateRegion().Clear();
708 //-----------------------------------------------------------------------------
709 // "draw" of m_wxwindow
710 //-----------------------------------------------------------------------------
712 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
715 wxapp_install_idle_handler();
720 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
721 rect
->width
, rect
->height
);
724 wxPrintf( "OnDraw from " );
725 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
726 printf( win->GetClassInfo()->GetClassName() );
727 wxPrintf( " %d %d %d %d\n", (int)rect->x,
733 wxEraseEvent
eevent( win
->GetId() );
734 eevent
.SetEventObject( win
);
735 win
->GetEventHandler()->ProcessEvent(eevent
);
737 wxPaintEvent
event( win
->GetId() );
738 event
.SetEventObject( win
);
739 win
->GetEventHandler()->ProcessEvent( event
);
741 win
->GetUpdateRegion().Clear();
744 //-----------------------------------------------------------------------------
745 // "key_press_event" from any window
746 //-----------------------------------------------------------------------------
748 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
751 wxapp_install_idle_handler();
753 if (!win
->m_hasVMT
) return FALSE
;
754 if (g_blockEventsOnDrag
) return FALSE
;
757 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
758 if (gdk_event->state & GDK_SHIFT_MASK)
759 printf( "ShiftDown.\n" );
761 printf( "ShiftUp.\n" );
762 if (gdk_event->state & GDK_CONTROL_MASK)
763 printf( "ControlDown.\n" );
765 printf( "ControlUp.\n" );
770 GdkModifierType state
;
771 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
773 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
775 /* sending unknown key events doesn't really make sense */
776 if (key_code
== 0) return FALSE
;
780 wxKeyEvent
event( wxEVT_KEY_DOWN
);
781 event
.SetTimestamp( gdk_event
->time
);
782 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
783 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
784 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
785 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
786 event
.m_keyCode
= key_code
;
787 event
.m_scanCode
= gdk_event
->keyval
;
790 event
.SetEventObject( win
);
791 ret
= win
->GetEventHandler()->ProcessEvent( event
);
793 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
798 wxWindow
*ancestor
= win
;
801 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
804 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
805 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
808 ancestor
= ancestor
->GetParent();
811 #endif // wxUSE_ACCEL
812 /* wxMSW doesn't send char events with Alt pressed */
813 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
814 will only be sent if it is not a menu accelerator. */
815 if ((key_code
!= 0) && ! ret
)
817 wxKeyEvent
event2( wxEVT_CHAR
);
818 event2
.SetTimestamp( gdk_event
->time
);
819 event2
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
820 event2
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
821 event2
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
822 event2
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
823 event2
.m_keyCode
= key_code
;
824 event2
.m_scanCode
= gdk_event
->keyval
;
827 event2
.SetEventObject( win
);
828 ret
= (ret
|| win
->GetEventHandler()->ProcessEvent( event2
));
831 /* win is a control: tab can be propagated up */
833 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
834 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
836 wxNavigationKeyEvent new_event
;
837 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
838 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
839 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
840 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
841 new_event
.SetCurrentFocus( win
);
842 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
845 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
847 (gdk_event
->keyval
== GDK_Escape
) )
849 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
850 new_event
.SetEventObject( win
);
851 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
854 #if (GTK_MINOR_VERSION > 0)
855 /* pressing F10 will activate the menu bar of the top frame */
857 (gdk_event
->keyval
== GDK_F10
) )
859 wxWindow
*ancestor
= win
;
862 if (wxIsKindOf(ancestor
,wxFrame
))
864 wxFrame
*frame
= (wxFrame
*) ancestor
;
865 wxMenuBar
*menubar
= frame
->GetMenuBar();
868 wxNode
*node
= menubar
->GetMenus().First();
871 // doesn't work correctly
872 // wxMenu *firstMenu = (wxMenu*) node->Data();
873 // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
879 ancestor
= ancestor
->GetParent();
885 Damn, I forgot why this didn't work, but it didn't work.
887 // win is a panel: up can be propagated to the panel
888 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
889 (gdk_event->keyval == GDK_Up))
891 win->m_parent->SetFocus();
895 // win is a panel: left/right can be propagated to the panel
896 if ((!ret) && (win->m_wxwindow) &&
897 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
898 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
900 wxNavigationKeyEvent new_event;
901 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
902 new_event.SetCurrentFocus( win );
903 ret = win->GetEventHandler()->ProcessEvent( new_event );
909 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
916 //-----------------------------------------------------------------------------
917 // "key_release_event" from any window
918 //-----------------------------------------------------------------------------
920 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
923 wxapp_install_idle_handler();
925 if (!win
->m_hasVMT
) return FALSE
;
926 if (g_blockEventsOnDrag
) return FALSE
;
929 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
930 if (gdk_event->state & GDK_SHIFT_MASK)
931 printf( "ShiftDown.\n" );
933 printf( "ShiftUp.\n" );
934 if (gdk_event->state & GDK_CONTROL_MASK)
935 printf( "ControlDown.\n" );
937 printf( "ControlUp.\n" );
941 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
943 /* sending unknown key events doesn't really make sense */
944 if (key_code
== 0) return FALSE
;
948 GdkModifierType state
;
949 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
951 wxKeyEvent
event( wxEVT_KEY_UP
);
952 event
.SetTimestamp( gdk_event
->time
);
953 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
954 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
955 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
956 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
957 event
.m_keyCode
= key_code
;
958 event
.m_scanCode
= gdk_event
->keyval
;
961 event
.SetEventObject( win
);
963 if (win
->GetEventHandler()->ProcessEvent( event
))
965 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
972 //-----------------------------------------------------------------------------
973 // "button_press_event"
974 //-----------------------------------------------------------------------------
976 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
979 wxapp_install_idle_handler();
982 wxPrintf( wxT("1) OnButtonPress from ") );
983 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
984 wxPrintf( win->GetClassInfo()->GetClassName() );
985 wxPrintf( wxT(".\n") );
987 if (!win
->m_hasVMT
) return FALSE
;
988 if (g_blockEventsOnDrag
) return TRUE
;
989 if (g_blockEventsOnScroll
) return TRUE
;
991 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
995 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
997 gtk_widget_grab_focus (win
->m_wxwindow
);
1000 wxPrintf( wxT("GrabFocus from ") );
1001 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1002 wxPrintf( win->GetClassInfo()->GetClassName() );
1003 wxPrintf( wxT(".\n") );
1010 wxPrintf( wxT("2) OnButtonPress from ") );
1011 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1012 wxPrintf( win->GetClassInfo()->GetClassName() );
1013 wxPrintf( wxT(".\n") );
1016 wxEventType event_type
= wxEVT_LEFT_DOWN
;
1018 if (gdk_event
->button
== 1)
1020 switch (gdk_event
->type
)
1022 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
1023 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
1027 else if (gdk_event
->button
== 2)
1029 switch (gdk_event
->type
)
1031 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
1032 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
1036 else if (gdk_event
->button
== 3)
1038 switch (gdk_event
->type
)
1040 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
1041 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
1046 wxMouseEvent
event( event_type
);
1047 event
.SetTimestamp( gdk_event
->time
);
1048 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1049 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1050 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1051 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1052 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1053 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1054 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1056 event
.m_x
= (long)gdk_event
->x
;
1057 event
.m_y
= (long)gdk_event
->y
;
1059 // Some control don't have their own X window and thus cannot get
1062 if (!g_captureWindow
)
1064 wxNode
*node
= win
->GetChildren().First();
1067 wxWindow
*child
= (wxWindow
*)node
->Data();
1069 if (child
->m_isStaticBox
)
1071 // wxStaticBox is transparent in the box itself
1074 int xx1
= child
->m_x
;
1075 int yy1
= child
->m_y
;
1076 int xx2
= child
->m_x
+ child
->m_width
;
1077 int yy2
= child
->m_x
+ child
->m_height
;
1080 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1082 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1084 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1086 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1089 event
.m_x
-= child
->m_x
;
1090 event
.m_y
-= child
->m_y
;
1097 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1098 (child
->m_x
<= event
.m_x
) &&
1099 (child
->m_y
<= event
.m_y
) &&
1100 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1101 (child
->m_y
+child
->m_height
>= event
.m_y
))
1104 event
.m_x
-= child
->m_x
;
1105 event
.m_y
-= child
->m_y
;
1109 node
= node
->Next();
1113 event
.SetEventObject( win
);
1115 gs_timeLastClick
= gdk_event
->time
;
1117 if (win
->GetEventHandler()->ProcessEvent( event
))
1119 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
1126 //-----------------------------------------------------------------------------
1127 // "button_release_event"
1128 //-----------------------------------------------------------------------------
1130 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1133 wxapp_install_idle_handler();
1135 if (!win
->m_hasVMT
) return FALSE
;
1136 if (g_blockEventsOnDrag
) return FALSE
;
1137 if (g_blockEventsOnScroll
) return FALSE
;
1139 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1142 printf( "OnButtonRelease from " );
1143 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1144 printf( win->GetClassInfo()->GetClassName() );
1148 wxEventType event_type
= wxEVT_NULL
;
1150 switch (gdk_event
->button
)
1152 case 1: event_type
= wxEVT_LEFT_UP
; break;
1153 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
1154 case 3: event_type
= wxEVT_RIGHT_UP
; break;
1157 wxMouseEvent
event( event_type
);
1158 event
.SetTimestamp( gdk_event
->time
);
1159 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1160 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1161 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1162 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1163 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1164 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1165 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1166 event
.m_x
= (long)gdk_event
->x
;
1167 event
.m_y
= (long)gdk_event
->y
;
1169 // Some control don't have their own X window and thus cannot get
1172 if (!g_captureWindow
)
1174 wxNode
*node
= win
->GetChildren().First();
1177 wxWindow
*child
= (wxWindow
*)node
->Data();
1179 if (child
->m_isStaticBox
)
1181 // wxStaticBox is transparent in the box itself
1184 int xx1
= child
->m_x
;
1185 int yy1
= child
->m_y
;
1186 int xx2
= child
->m_x
+ child
->m_width
;
1187 int yy2
= child
->m_x
+ child
->m_height
;
1190 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1192 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1194 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1196 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1199 event
.m_x
-= child
->m_x
;
1200 event
.m_y
-= child
->m_y
;
1207 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1208 (child
->m_x
<= event
.m_x
) &&
1209 (child
->m_y
<= event
.m_y
) &&
1210 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1211 (child
->m_y
+child
->m_height
>= event
.m_y
))
1214 event
.m_x
-= child
->m_x
;
1215 event
.m_y
-= child
->m_y
;
1219 node
= node
->Next();
1223 event
.SetEventObject( win
);
1225 if (win
->GetEventHandler()->ProcessEvent( event
))
1227 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1234 //-----------------------------------------------------------------------------
1235 // "motion_notify_event"
1236 //-----------------------------------------------------------------------------
1238 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1241 wxapp_install_idle_handler();
1243 if (!win
->m_hasVMT
) return FALSE
;
1244 if (g_blockEventsOnDrag
) return FALSE
;
1245 if (g_blockEventsOnScroll
) return FALSE
;
1247 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1249 if (gdk_event
->is_hint
)
1253 GdkModifierType state
;
1254 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1260 printf( "OnMotion from " );
1261 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1262 printf( win->GetClassInfo()->GetClassName() );
1266 wxMouseEvent
event( wxEVT_MOTION
);
1267 event
.SetTimestamp( gdk_event
->time
);
1268 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1269 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1270 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1271 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1272 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1273 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1274 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1276 event
.m_x
= (long)gdk_event
->x
;
1277 event
.m_y
= (long)gdk_event
->y
;
1279 // Some control don't have their own X window and thus cannot get
1282 if (!g_captureWindow
)
1284 wxNode
*node
= win
->GetChildren().First();
1287 wxWindow
*child
= (wxWindow
*)node
->Data();
1289 if (child
->m_isStaticBox
)
1291 // wxStaticBox is transparent in the box itself
1294 int xx1
= child
->m_x
;
1295 int yy1
= child
->m_y
;
1296 int xx2
= child
->m_x
+ child
->m_width
;
1297 int yy2
= child
->m_x
+ child
->m_height
;
1300 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1302 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1304 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1306 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1309 event
.m_x
-= child
->m_x
;
1310 event
.m_y
-= child
->m_y
;
1317 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1318 (child
->m_x
<= event
.m_x
) &&
1319 (child
->m_y
<= event
.m_y
) &&
1320 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1321 (child
->m_y
+child
->m_height
>= event
.m_y
))
1324 event
.m_x
-= child
->m_x
;
1325 event
.m_y
-= child
->m_y
;
1329 node
= node
->Next();
1333 event
.SetEventObject( win
);
1335 if (win
->GetEventHandler()->ProcessEvent( event
))
1337 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1344 //-----------------------------------------------------------------------------
1346 //-----------------------------------------------------------------------------
1348 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1351 wxapp_install_idle_handler();
1353 if (!win
->m_hasVMT
) return FALSE
;
1354 if (g_blockEventsOnDrag
) return FALSE
;
1356 g_focusWindow
= win
;
1358 if (win
->m_wxwindow
)
1360 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1362 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1364 printf( "SetFocus flag from " );
1365 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1366 printf( win->GetClassInfo()->GetClassName() );
1374 printf( "OnSetFocus from " );
1375 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1376 printf( win->GetClassInfo()->GetClassName() );
1378 printf( WXSTRINGCAST win->GetLabel() );
1382 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1383 event
.SetEventObject( win
);
1385 if (win
->GetEventHandler()->ProcessEvent( event
))
1387 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1394 //-----------------------------------------------------------------------------
1395 // "focus_out_event"
1396 //-----------------------------------------------------------------------------
1398 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1401 wxapp_install_idle_handler();
1403 if (!win
->m_hasVMT
) return FALSE
;
1404 if (g_blockEventsOnDrag
) return FALSE
;
1406 if (win
->m_wxwindow
)
1408 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1409 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1413 printf( "OnKillFocus from " );
1414 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1415 printf( win->GetClassInfo()->GetClassName() );
1419 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1420 event
.SetEventObject( win
);
1422 if (win
->GetEventHandler()->ProcessEvent( event
))
1424 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1431 //-----------------------------------------------------------------------------
1432 // "enter_notify_event"
1433 //-----------------------------------------------------------------------------
1435 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1438 wxapp_install_idle_handler();
1440 if (!win
->m_hasVMT
) return FALSE
;
1441 if (g_blockEventsOnDrag
) return FALSE
;
1443 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1445 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1446 #if (GTK_MINOR_VERSION > 0)
1447 event
.SetTimestamp( gdk_event
->time
);
1449 event
.SetEventObject( win
);
1453 GdkModifierType state
= (GdkModifierType
)0;
1455 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1457 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1458 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1459 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1460 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1461 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1462 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1463 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1465 event
.m_x
= (long)x
;
1466 event
.m_y
= (long)y
;
1468 if (win
->GetEventHandler()->ProcessEvent( event
))
1470 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1477 //-----------------------------------------------------------------------------
1478 // "leave_notify_event"
1479 //-----------------------------------------------------------------------------
1481 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1484 wxapp_install_idle_handler();
1486 if (!win
->m_hasVMT
) return FALSE
;
1487 if (g_blockEventsOnDrag
) return FALSE
;
1489 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1491 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1492 #if (GTK_MINOR_VERSION > 0)
1493 event
.SetTimestamp( gdk_event
->time
);
1495 event
.SetEventObject( win
);
1499 GdkModifierType state
= (GdkModifierType
)0;
1501 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1503 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1504 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1505 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1506 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1507 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1508 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1509 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1511 event
.m_x
= (long)x
;
1512 event
.m_y
= (long)y
;
1514 if (win
->GetEventHandler()->ProcessEvent( event
))
1516 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1523 //-----------------------------------------------------------------------------
1524 // "value_changed" from m_vAdjust
1525 //-----------------------------------------------------------------------------
1527 static void gtk_window_vscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1530 wxapp_install_idle_handler();
1532 if (g_blockEventsOnDrag
) return;
1534 if (!win
->m_hasVMT
) return;
1536 float diff
= adjust
->value
- win
->m_oldVerticalPos
;
1537 if (fabs(diff
) < 0.2) return;
1539 win
->m_oldVerticalPos
= adjust
->value
;
1541 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1542 GtkRange
*range
= GTK_RANGE( scrolledWindow
->vscrollbar
);
1544 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1545 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1546 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1547 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1548 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1550 int value
= (int)(adjust
->value
+0.5);
1552 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1553 event
.SetEventObject( win
);
1554 win
->GetEventHandler()->ProcessEvent( event
);
1557 //-----------------------------------------------------------------------------
1558 // "value_changed" from m_hAdjust
1559 //-----------------------------------------------------------------------------
1561 static void gtk_window_hscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1564 wxapp_install_idle_handler();
1566 if (g_blockEventsOnDrag
) return;
1567 if (!win
->m_hasVMT
) return;
1569 float diff
= adjust
->value
- win
->m_oldHorizontalPos
;
1570 if (fabs(diff
) < 0.2) return;
1572 win
->m_oldHorizontalPos
= adjust
->value
;
1574 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1575 GtkRange
*range
= GTK_RANGE( scrolledWindow
->hscrollbar
);
1577 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1578 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1579 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1580 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1581 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1583 int value
= (int)(adjust
->value
+0.5);
1585 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1586 event
.SetEventObject( win
);
1587 win
->GetEventHandler()->ProcessEvent( event
);
1590 //-----------------------------------------------------------------------------
1591 // "changed" from m_vAdjust
1592 //-----------------------------------------------------------------------------
1594 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1597 wxapp_install_idle_handler();
1599 if (g_blockEventsOnDrag
) return;
1600 if (!win
->m_hasVMT
) return;
1602 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1603 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1605 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1606 event
.SetEventObject( win
);
1607 win
->GetEventHandler()->ProcessEvent( event
);
1610 //-----------------------------------------------------------------------------
1611 // "changed" from m_hAdjust
1612 //-----------------------------------------------------------------------------
1614 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1617 wxapp_install_idle_handler();
1619 if (g_blockEventsOnDrag
) return;
1620 if (!win
->m_hasVMT
) return;
1622 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1623 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1625 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1626 event
.SetEventObject( win
);
1627 win
->GetEventHandler()->ProcessEvent( event
);
1630 //-----------------------------------------------------------------------------
1631 // "button_press_event" from scrollbar
1632 //-----------------------------------------------------------------------------
1634 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1635 GdkEventButton
*WXUNUSED(gdk_event
),
1639 wxapp_install_idle_handler();
1641 // don't test here as we can release the mouse while being over
1642 // a different window than the slider
1644 // if (gdk_event->window != widget->slider) return FALSE;
1646 win
->SetScrolling( TRUE
);
1651 //-----------------------------------------------------------------------------
1652 // "button_release_event" from scrollbar
1653 //-----------------------------------------------------------------------------
1655 static gint
gtk_scrollbar_button_release_callback( GtkRange
*WXUNUSED(widget
),
1656 GdkEventButton
*WXUNUSED(gdk_event
),
1660 // don't test here as we can release the mouse while being over
1661 // a different window than the slider
1663 // if (gdk_event->window != widget->slider) return FALSE;
1665 win
->SetScrolling( FALSE
);
1670 // ----------------------------------------------------------------------------
1671 // this wxWindowBase function is implemented here (in platform-specific file)
1672 // because it is static and so couldn't be made virtual
1673 // ----------------------------------------------------------------------------
1675 wxWindow
*wxWindowBase::FindFocus()
1677 return g_focusWindow
;
1680 //-----------------------------------------------------------------------------
1681 // "realize" from m_widget
1682 //-----------------------------------------------------------------------------
1684 /* we cannot set colours and fonts before the widget has
1685 been realized, so we do this directly after realization */
1688 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1691 wxapp_install_idle_handler();
1693 if (win
->m_delayedFont
)
1694 win
->SetFont( win
->GetFont() );
1696 if (win
->m_delayedBackgroundColour
)
1697 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1699 if (win
->m_delayedForegroundColour
)
1700 win
->SetForegroundColour( win
->GetForegroundColour() );
1702 wxWindowCreateEvent
event( win
);
1703 event
.SetEventObject( win
);
1704 win
->GetEventHandler()->ProcessEvent( event
);
1709 //-----------------------------------------------------------------------------
1710 // InsertChild for wxWindow.
1711 //-----------------------------------------------------------------------------
1713 /* Callback for wxWindow. This very strange beast has to be used because
1714 * C++ has no virtual methods in a constructor. We have to emulate a
1715 * virtual function here as wxNotebook requires a different way to insert
1716 * a child in it. I had opted for creating a wxNotebookPage window class
1717 * which would have made this superfluous (such in the MDI window system),
1718 * but no-one was listening to me... */
1720 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1722 /* the window might have been scrolled already, do we
1723 have to adapt the position */
1724 GtkMyFixed
*myfixed
= GTK_MYFIXED(parent
->m_wxwindow
);
1725 child
->m_x
+= myfixed
->xoffset
;
1726 child
->m_y
+= myfixed
->yoffset
;
1728 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1729 GTK_WIDGET(child
->m_widget
),
1735 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1737 /* we now allow a window to get the focus as long as it
1738 doesn't have any children. */
1739 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1743 //-----------------------------------------------------------------------------
1745 //-----------------------------------------------------------------------------
1747 wxWindow
* wxGetActiveWindow()
1749 return g_focusWindow
;
1752 //-----------------------------------------------------------------------------
1754 //-----------------------------------------------------------------------------
1756 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1758 void wxWindow::Init()
1764 m_widget
= (GtkWidget
*) NULL
;
1765 m_wxwindow
= (GtkWidget
*) NULL
;
1775 m_needParent
= TRUE
;
1776 m_isBeingDeleted
= FALSE
;
1780 m_hasScrolling
= FALSE
;
1781 m_isScrolling
= FALSE
;
1783 m_hAdjust
= (GtkAdjustment
*) NULL
;
1784 m_vAdjust
= (GtkAdjustment
*) NULL
;
1785 m_oldHorizontalPos
= 0.0;
1786 m_oldVerticalPos
= 0.0;
1789 m_widgetStyle
= (GtkStyle
*) NULL
;
1791 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1793 m_isStaticBox
= FALSE
;
1794 m_isRadioButton
= FALSE
;
1796 m_acceptsFocus
= FALSE
;
1798 m_cursor
= *wxSTANDARD_CURSOR
;
1801 wxWindow::wxWindow()
1806 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1807 const wxPoint
&pos
, const wxSize
&size
,
1808 long style
, const wxString
&name
)
1812 Create( parent
, id
, pos
, size
, style
, name
);
1815 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1816 const wxPoint
&pos
, const wxSize
&size
,
1817 long style
, const wxString
&name
)
1819 if (!PreCreation( parent
, pos
, size
) ||
1820 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
1822 wxFAIL_MSG( wxT("wxWindow creation failed") );
1826 m_insertCallback
= wxInsertChildInWindow
;
1828 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1829 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1832 debug_focus_in( m_widget
, wxT("wxWindow::m_widget"), name
);
1835 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1838 debug_focus_in( scrolledWindow
->hscrollbar
, wxT("wxWindow::hsrcollbar"), name
);
1839 debug_focus_in( scrolledWindow
->vscrollbar
, wxT("wxWindow::vsrcollbar"), name
);
1842 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1843 scroll_class
->scrollbar_spacing
= 0;
1845 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1847 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1848 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1850 m_wxwindow
= gtk_myfixed_new();
1853 debug_focus_in( m_wxwindow
, wxT("wxWindow::m_wxwindow"), name
);
1856 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1858 #if (GTK_MINOR_VERSION > 0)
1859 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1861 if (HasFlag(wxRAISED_BORDER
))
1863 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_OUT
);
1865 else if (HasFlag(wxSUNKEN_BORDER
))
1867 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_IN
);
1869 else if (HasFlag(wxSIMPLE_BORDER
))
1871 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_THIN
);
1875 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_NONE
);
1877 #else // GTK_MINOR_VERSION == 0
1878 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1880 if (HasFlag(wxRAISED_BORDER
))
1882 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1884 else if (HasFlag(wxSUNKEN_BORDER
))
1886 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1890 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1892 #endif // GTK_MINOR_VERSION
1894 if (HasFlag(wxTAB_TRAVERSAL
))
1896 /* we now allow a window to get the focus as long as it
1897 doesn't have any children. */
1898 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1899 m_acceptsFocus
= FALSE
;
1903 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1904 m_acceptsFocus
= TRUE
;
1907 #if (GTK_MINOR_VERSION == 0)
1908 // shut the viewport up
1909 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1910 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1911 #endif // GTK_MINOR_VERSION == 0
1913 // I _really_ don't want scrollbars in the beginning
1914 m_vAdjust
->lower
= 0.0;
1915 m_vAdjust
->upper
= 1.0;
1916 m_vAdjust
->value
= 0.0;
1917 m_vAdjust
->step_increment
= 1.0;
1918 m_vAdjust
->page_increment
= 1.0;
1919 m_vAdjust
->page_size
= 5.0;
1920 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1921 m_hAdjust
->lower
= 0.0;
1922 m_hAdjust
->upper
= 1.0;
1923 m_hAdjust
->value
= 0.0;
1924 m_hAdjust
->step_increment
= 1.0;
1925 m_hAdjust
->page_increment
= 1.0;
1926 m_hAdjust
->page_size
= 5.0;
1927 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1929 // these handlers block mouse events to any window during scrolling such as
1930 // motion events and prevent GTK and wxWindows from fighting over where the
1933 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1934 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1936 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1937 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1939 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1940 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1942 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1943 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1945 // these handlers get notified when screen updates are required either when
1946 // scrolling or when the window size (and therefore scrollbar configuration)
1949 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1950 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1951 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1952 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1954 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1955 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1956 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1957 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1959 gtk_widget_show( m_wxwindow
);
1962 m_parent
->DoAddChild( this );
1971 wxWindow::~wxWindow()
1973 m_isBeingDeleted
= TRUE
;
1982 m_parent
->RemoveChild( this );
1986 gtk_style_unref( m_widgetStyle
);
1987 m_widgetStyle
= (GtkStyle
*) NULL
;
1992 gtk_widget_destroy( m_wxwindow
);
1993 m_wxwindow
= (GtkWidget
*) NULL
;
1998 gtk_widget_destroy( m_widget
);
1999 m_widget
= (GtkWidget
*) NULL
;
2003 bool wxWindow::PreCreation( wxWindow
*parent
, const wxPoint
&pos
, const wxSize
&size
)
2005 wxCHECK_MSG( !m_needParent
|| parent
, FALSE
, wxT("Need complete parent.") );
2007 /* this turns -1 into 20 so that a minimal window is
2008 visible even although -1,-1 has been given as the
2009 size of the window. the same trick is used in other
2010 ports and should make debugging easier */
2011 m_width
= WidthDefault(size
.x
);
2012 m_height
= HeightDefault(size
.y
);
2017 /* some reasonable defaults */
2022 m_x
= (gdk_screen_width () - m_width
) / 2;
2023 if (m_x
< 10) m_x
= 10;
2027 m_y
= (gdk_screen_height () - m_height
) / 2;
2028 if (m_y
< 10) m_y
= 10;
2035 void wxWindow::PostCreation()
2037 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2043 /* these get reported to wxWindows -> wxPaintEvent */
2044 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
2045 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
2047 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
2048 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
2051 #if (GTK_MINOR_VERSION > 0)
2052 /* these are called when the "sunken" or "raised" borders are drawn */
2053 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
2054 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
2056 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
2057 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
2061 GtkWidget
*connect_widget
= GetConnectWidget();
2063 ConnectWidget( connect_widget
);
2065 /* we cannot set colours, fonts and cursors before the widget has
2066 been realized, so we do this directly after realization */
2067 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
2068 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
2073 void wxWindow::ConnectWidget( GtkWidget
*widget
)
2075 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
2076 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
2078 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
2079 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
2081 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
2082 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
2084 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
2085 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
2087 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
2088 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
2090 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
2091 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2093 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
2094 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2096 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
2097 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
2099 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
2100 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
2103 bool wxWindow::Destroy()
2105 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2109 return wxWindowBase::Destroy();
2112 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
2114 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2115 wxASSERT_MSG( (m_parent
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") );
2117 if (m_resizing
) return; /* I don't like recursions */
2120 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
2122 /* don't set the size for children of wxNotebook, just take the values. */
2130 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_parent
->m_wxwindow
);
2132 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
2134 if (x
!= -1) m_x
= x
+ myfixed
->xoffset
;
2135 if (y
!= -1) m_y
= y
+ myfixed
->yoffset
;
2136 if (width
!= -1) m_width
= width
;
2137 if (height
!= -1) m_height
= height
;
2141 m_x
= x
+ myfixed
->xoffset
;
2142 m_y
= y
+ myfixed
->yoffset
;
2147 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2149 if (width
== -1) m_width
= 80;
2152 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2154 if (height
== -1) m_height
= 26;
2157 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2158 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2159 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2160 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2163 int bottom_border
= 0;
2165 if (GTK_WIDGET_CAN_DEFAULT(m_widget
))
2167 /* the default button has a border around it */
2172 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
2177 m_height
+border
+bottom_border
);
2181 wxPrintf( "OnSize sent from " );
2182 if (GetClassInfo() && GetClassInfo()->GetClassName())
2183 wxPrintf( GetClassInfo()->GetClassName() );
2184 wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height );
2187 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2188 event
.SetEventObject( this );
2189 GetEventHandler()->ProcessEvent( event
);
2194 void wxWindow::OnInternalIdle()
2196 wxCursor cursor
= m_cursor
;
2197 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2201 /* I now set the cursor the anew in every OnInternalIdle call
2202 as setting the cursor in a parent window also effects the
2203 windows above so that checking for the current cursor is
2208 GdkWindow
*window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2210 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2212 if (!g_globalCursor
.Ok())
2213 cursor
= *wxSTANDARD_CURSOR
;
2215 window
= m_widget
->window
;
2216 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2217 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2223 GdkWindow
*window
= m_widget
->window
;
2224 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2225 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2233 void wxWindow::DoGetSize( int *width
, int *height
) const
2235 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2237 if (width
) (*width
) = m_width
;
2238 if (height
) (*height
) = m_height
;
2241 void wxWindow::DoSetClientSize( int width
, int height
)
2243 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2247 SetSize( width
, height
);
2254 #if (GTK_MINOR_VERSION == 0)
2255 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2259 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2260 #if 0 // unused - if this is ok, just remove this line (VZ)
2261 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2264 GtkWidget
*viewport
= scroll_window
->viewport
;
2265 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2267 dw
+= 2 * viewport_class
->xthickness
;
2268 dh
+= 2 * viewport_class
->ythickness
;
2272 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2274 /* when using GTK 1.2 we set the shadow border size to 2 */
2278 if (HasFlag(wxSIMPLE_BORDER
))
2280 /* when using GTK 1.2 we set the simple border size to 1 */
2289 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2290 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2292 we use this instead: range.slider_width = 11 + 2*2pts edge
2295 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2296 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2298 if (scroll_window
->vscrollbar_visible
)
2300 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2301 dw
+= scroll_class
->scrollbar_spacing
;
2304 if (scroll_window
->hscrollbar_visible
)
2306 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2307 dh
+= scroll_class
->scrollbar_spacing
;
2311 SetSize( width
+dw
, height
+dh
);
2315 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2317 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2321 if (width
) (*width
) = m_width
;
2322 if (height
) (*height
) = m_height
;
2329 #if (GTK_MINOR_VERSION == 0)
2330 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2334 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2335 #if 0 // unused - if this is ok, just remove this line (VZ)
2336 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2339 GtkWidget
*viewport
= scroll_window
->viewport
;
2340 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2342 dw
+= 2 * viewport_class
->xthickness
;
2343 dh
+= 2 * viewport_class
->ythickness
;
2347 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2349 /* when using GTK 1.2 we set the shadow border size to 2 */
2353 if (HasFlag(wxSIMPLE_BORDER
))
2355 /* when using GTK 1.2 we set the simple border size to 1 */
2363 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2364 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2366 we use this instead: range.slider_width = 11 + 2*2pts edge
2369 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2370 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2372 if (scroll_window
->vscrollbar_visible
)
2374 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2375 dw
+= scroll_class
->scrollbar_spacing
;
2378 if (scroll_window
->hscrollbar_visible
)
2380 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2381 dh
+= scroll_class
->scrollbar_spacing
;
2385 if (width
) (*width
) = m_width
- dw
;
2386 if (height
) (*height
) = m_height
- dh
;
2390 void wxWindow::DoGetPosition( int *x
, int *y
) const
2392 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2396 if (m_parent
&& m_parent
->m_wxwindow
)
2398 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_parent
->m_wxwindow
);
2399 dx
= myfixed
->xoffset
;
2400 dy
= myfixed
->yoffset
;
2403 if (x
) (*x
) = m_x
- dx
;
2404 if (y
) (*y
) = m_y
- dy
;
2407 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2409 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2411 if (!m_widget
->window
) return;
2413 GdkWindow
*source
= (GdkWindow
*) NULL
;
2415 source
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2417 source
= m_widget
->window
;
2421 gdk_window_get_origin( source
, &org_x
, &org_y
);
2425 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2427 org_x
+= m_widget
->allocation
.x
;
2428 org_y
+= m_widget
->allocation
.y
;
2436 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2438 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2440 if (!m_widget
->window
) return;
2442 GdkWindow
*source
= (GdkWindow
*) NULL
;
2444 source
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2446 source
= m_widget
->window
;
2450 gdk_window_get_origin( source
, &org_x
, &org_y
);
2454 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2456 org_x
+= m_widget
->allocation
.x
;
2457 org_y
+= m_widget
->allocation
.y
;
2465 bool wxWindow::Show( bool show
)
2467 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2469 if (!wxWindowBase::Show(show
))
2476 gtk_widget_show( m_widget
);
2478 gtk_widget_hide( m_widget
);
2483 bool wxWindow::Enable( bool enable
)
2485 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2487 if (!wxWindowBase::Enable(enable
))
2493 gtk_widget_set_sensitive( m_widget
, enable
);
2495 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2500 int wxWindow::GetCharHeight() const
2502 wxCHECK_MSG( (m_widget
!= NULL
), 12, wxT("invalid window") );
2504 wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") );
2506 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2508 return font
->ascent
+ font
->descent
;
2511 int wxWindow::GetCharWidth() const
2513 wxCHECK_MSG( (m_widget
!= NULL
), 8, wxT("invalid window") );
2515 wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") );
2517 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2519 return gdk_string_width( font
, "H" );
2522 void wxWindow::GetTextExtent( const wxString
& string
,
2526 int *externalLeading
,
2527 const wxFont
*theFont
) const
2529 wxFont fontToUse
= m_font
;
2530 if (theFont
) fontToUse
= *theFont
;
2532 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
2534 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2535 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2536 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2537 if (descent
) (*descent
) = font
->descent
;
2538 if (externalLeading
) (*externalLeading
) = 0; // ??
2541 void wxWindow::SetFocus()
2543 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2545 GtkWidget
*connect_widget
= GetConnectWidget();
2548 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2550 gtk_widget_grab_focus (connect_widget
);
2552 else if (GTK_IS_CONTAINER(connect_widget
))
2554 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2562 bool wxWindow::AcceptsFocus() const
2564 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2567 bool wxWindow::Reparent( wxWindowBase
*newParentBase
)
2569 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2571 wxWindow
*oldParent
= m_parent
,
2572 *newParent
= (wxWindow
*)newParentBase
;
2574 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2576 if ( !wxWindowBase::Reparent(newParent
) )
2579 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2581 /* prevent GTK from deleting the widget arbitrarily */
2582 gtk_widget_ref( m_widget
);
2586 gtk_container_remove( GTK_CONTAINER(oldParent
->m_wxwindow
), m_widget
);
2589 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2593 /* insert GTK representation */
2594 (*(newParent
->m_insertCallback
))(newParent
, this);
2597 /* reverse: prevent GTK from deleting the widget arbitrarily */
2598 gtk_widget_unref( m_widget
);
2603 void wxWindow::DoAddChild(wxWindow
*child
)
2605 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2607 wxASSERT_MSG( (child
!= NULL
), wxT("invalid child window") );
2609 wxASSERT_MSG( (m_insertCallback
!= NULL
), wxT("invalid child insertion function") );
2614 /* insert GTK representation */
2615 (*m_insertCallback
)(this, child
);
2618 void wxWindow::Raise()
2620 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2622 if (!m_widget
->window
) return;
2624 gdk_window_raise( m_widget
->window
);
2627 void wxWindow::Lower()
2629 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2631 if (!m_widget
->window
) return;
2633 gdk_window_lower( m_widget
->window
);
2636 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2638 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2640 return wxWindowBase::SetCursor( cursor
);
2643 void wxWindow::WarpPointer( int x
, int y
)
2645 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2647 /* we provide this function ourselves as it is
2648 missing in GDK (top of this file) */
2650 GdkWindow
*window
= (GdkWindow
*) NULL
;
2652 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2654 window
= GetConnectWidget()->window
;
2657 gdk_window_warp_pointer( window
, x
, y
);
2660 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2662 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2664 if (!m_widget
->window
) return;
2666 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2670 gdk_window_clear_area( GTK_MYFIXED(m_wxwindow
)->bin_window
,
2672 rect
->width
, rect
->height
);
2676 gdk_window_clear( GTK_MYFIXED(m_wxwindow
)->bin_window
);
2680 /* there is no GTK equivalent of "draw only, don't clear" so we
2681 invent our own in the GtkMyFixed widget */
2687 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
2688 gboolean old_clear
= myfixed
->clear_on_draw
;
2689 gtk_my_fixed_set_clear( myfixed
, FALSE
);
2691 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2693 gtk_my_fixed_set_clear( myfixed
, old_clear
);
2696 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2700 GdkRectangle gdk_rect
;
2701 gdk_rect
.x
= rect
->x
;
2702 gdk_rect
.y
= rect
->y
;
2703 gdk_rect
.width
= rect
->width
;
2704 gdk_rect
.height
= rect
->height
;
2708 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
2709 gboolean old_clear
= myfixed
->clear_on_draw
;
2710 gtk_my_fixed_set_clear( myfixed
, FALSE
);
2712 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2714 gtk_my_fixed_set_clear( myfixed
, old_clear
);
2717 gtk_widget_draw( m_widget
, &gdk_rect
);
2721 void wxWindow::Clear()
2723 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2725 if (!m_widget
->window
) return;
2727 if (m_wxwindow
&& m_wxwindow
->window
)
2729 gdk_window_clear( m_wxwindow
->window
);
2734 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2736 wxWindowBase::DoSetToolTip(tip
);
2739 m_tooltip
->Apply( this );
2742 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2744 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2746 #endif // wxUSE_TOOLTIPS
2748 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2750 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2752 if (!wxWindowBase::SetBackgroundColour(colour
))
2754 // don't leave if the GTK widget has just
2756 if (!m_delayedBackgroundColour
) return FALSE
;
2759 GdkWindow
*window
= (GdkWindow
*) NULL
;
2761 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2763 window
= GetConnectWidget()->window
;
2767 // indicate that a new style has been set
2768 // but it couldn't get applied as the
2769 // widget hasn't been realized yet.
2770 m_delayedBackgroundColour
= TRUE
;
2772 // pretend we have done something
2778 /* wxMSW doesn't clear the window here. I don't do that either to
2779 provide compatibility. call Clear() to do the job. */
2781 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2782 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2785 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2786 if (sysbg
== m_backgroundColour
)
2788 m_backgroundColour
= wxNullColour
;
2790 m_backgroundColour
= sysbg
;
2800 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2802 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2804 if (!wxWindowBase::SetForegroundColour(colour
))
2806 // don't leave if the GTK widget has just
2808 if (!m_delayedForegroundColour
) return FALSE
;
2811 GdkWindow
*window
= (GdkWindow
*) NULL
;
2813 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2815 window
= GetConnectWidget()->window
;
2819 // indicate that a new style has been set
2820 // but it couldn't get applied as the
2821 // widget hasn't been realized yet.
2822 m_delayedForegroundColour
= TRUE
;
2824 // pretend we have done something
2828 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2829 if ( sysbg
== m_backgroundColour
)
2831 m_backgroundColour
= wxNullColour
;
2833 m_backgroundColour
= sysbg
;
2843 GtkStyle
*wxWindow::GetWidgetStyle()
2845 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2847 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2849 return m_widgetStyle
;
2852 void wxWindow::SetWidgetStyle()
2854 GtkStyle
*style
= GetWidgetStyle();
2856 gdk_font_unref( style
->font
);
2857 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2859 if (m_foregroundColour
.Ok())
2861 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2862 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2863 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2864 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2867 if (m_backgroundColour
.Ok())
2869 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2870 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2871 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2872 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2873 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2874 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2875 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2876 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2877 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2881 void wxWindow::ApplyWidgetStyle()
2885 //-----------------------------------------------------------------------------
2886 // Pop-up menu stuff
2887 //-----------------------------------------------------------------------------
2889 static void gtk_pop_hide_callback( GtkWidget
*WXUNUSED(widget
), bool* is_waiting
)
2891 *is_waiting
= FALSE
;
2894 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2896 menu
->SetInvokingWindow( win
);
2897 wxNode
*node
= menu
->GetItems().First();
2900 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2901 if (menuitem
->IsSubMenu())
2903 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2905 node
= node
->Next();
2909 static gint gs_pop_x
= 0;
2910 static gint gs_pop_y
= 0;
2912 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2916 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2921 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
2923 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2925 wxCHECK_MSG( menu
!= NULL
, FALSE
, wxT("invalid popup-menu") );
2927 SetInvokingWindow( menu
, this );
2934 bool is_waiting
= TRUE
;
2936 gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide",
2937 GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting
);
2940 GTK_MENU(menu
->m_menu
),
2941 (GtkWidget
*) NULL
, // parent menu shell
2942 (GtkWidget
*) NULL
, // parent menu item
2943 (GtkMenuPositionFunc
) pop_pos_callback
,
2944 (gpointer
) this, // client data
2945 0, // button used to activate it
2946 gs_timeLastClick
// the time of activation
2951 while (gtk_events_pending())
2952 gtk_main_iteration();
2958 #if wxUSE_DRAG_AND_DROP
2960 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2962 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2964 GtkWidget
*dnd_widget
= GetConnectWidget();
2966 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2968 if (m_dropTarget
) delete m_dropTarget
;
2969 m_dropTarget
= dropTarget
;
2971 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2974 #endif // wxUSE_DRAG_AND_DROP
2976 GtkWidget
* wxWindow::GetConnectWidget()
2978 GtkWidget
*connect_widget
= m_widget
;
2979 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2981 return connect_widget
;
2984 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2987 return (window
== GTK_MYFIXED(m_wxwindow
)->bin_window
);
2989 return (window
== m_widget
->window
);
2992 bool wxWindow::SetFont( const wxFont
&font
)
2994 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2996 if (!wxWindowBase::SetFont(font
))
2998 // don't leave if the GTK widget has just
3000 if (!m_delayedFont
) return FALSE
;
3003 GdkWindow
*window
= (GdkWindow
*) NULL
;
3005 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
3007 window
= GetConnectWidget()->window
;
3011 // indicate that a new style has been set
3012 // but it couldn't get applied as the
3013 // widget hasn't been realized yet.
3014 m_delayedFont
= TRUE
;
3016 // pretend we have done something
3020 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
3021 if ( sysbg
== m_backgroundColour
)
3023 m_backgroundColour
= wxNullColour
;
3025 m_backgroundColour
= sysbg
;
3035 void wxWindow::CaptureMouse()
3037 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3039 wxCHECK_RET( g_captureWindow
== NULL
, wxT("CaptureMouse called twice") );
3041 GdkWindow
*window
= (GdkWindow
*) NULL
;
3043 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
3045 window
= GetConnectWidget()->window
;
3047 if (!window
) return;
3049 gdk_pointer_grab( window
, FALSE
,
3051 (GDK_BUTTON_PRESS_MASK
|
3052 GDK_BUTTON_RELEASE_MASK
|
3053 GDK_POINTER_MOTION_HINT_MASK
|
3054 GDK_POINTER_MOTION_MASK
),
3056 m_cursor
.GetCursor(),
3058 g_captureWindow
= this;
3061 void wxWindow::ReleaseMouse()
3063 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3065 wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") );
3067 GdkWindow
*window
= (GdkWindow
*) NULL
;
3069 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
3071 window
= GetConnectWidget()->window
;
3073 if (!window
) return;
3075 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3076 g_captureWindow
= (wxWindow
*) NULL
;
3079 bool wxWindow::IsRetained() const
3084 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3085 int range
, bool refresh
)
3087 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3089 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3091 m_hasScrolling
= TRUE
;
3093 if (orient
== wxHORIZONTAL
)
3095 float fpos
= (float)pos
;
3096 float frange
= (float)range
;
3097 float fthumb
= (float)thumbVisible
;
3098 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3099 if (fpos
< 0.0) fpos
= 0.0;
3101 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3102 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3104 SetScrollPos( orient
, pos
, refresh
);
3108 m_oldHorizontalPos
= fpos
;
3110 m_hAdjust
->lower
= 0.0;
3111 m_hAdjust
->upper
= frange
;
3112 m_hAdjust
->value
= fpos
;
3113 m_hAdjust
->step_increment
= 1.0;
3114 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3115 m_hAdjust
->page_size
= fthumb
;
3119 float fpos
= (float)pos
;
3120 float frange
= (float)range
;
3121 float fthumb
= (float)thumbVisible
;
3122 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3123 if (fpos
< 0.0) fpos
= 0.0;
3125 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3126 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3128 SetScrollPos( orient
, pos
, refresh
);
3132 m_oldVerticalPos
= fpos
;
3134 m_vAdjust
->lower
= 0.0;
3135 m_vAdjust
->upper
= frange
;
3136 m_vAdjust
->value
= fpos
;
3137 m_vAdjust
->step_increment
= 1.0;
3138 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3139 m_vAdjust
->page_size
= fthumb
;
3142 if (orient
== wxHORIZONTAL
)
3143 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3145 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3148 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3150 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3152 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3154 if (orient
== wxHORIZONTAL
)
3156 float fpos
= (float)pos
;
3157 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3158 if (fpos
< 0.0) fpos
= 0.0;
3159 m_oldHorizontalPos
= fpos
;
3161 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3162 m_hAdjust
->value
= fpos
;
3166 float fpos
= (float)pos
;
3167 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3168 if (fpos
< 0.0) fpos
= 0.0;
3169 m_oldVerticalPos
= fpos
;
3171 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3172 m_vAdjust
->value
= fpos
;
3179 if (m_wxwindow
->window
)
3181 if (orient
== wxHORIZONTAL
)
3182 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3184 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3191 int wxWindow::GetScrollThumb( int orient
) const
3193 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3195 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3197 if (orient
== wxHORIZONTAL
)
3198 return (int)(m_hAdjust
->page_size
+0.5);
3200 return (int)(m_vAdjust
->page_size
+0.5);
3203 int wxWindow::GetScrollPos( int orient
) const
3205 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3207 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3209 if (orient
== wxHORIZONTAL
)
3210 return (int)(m_hAdjust
->value
+0.5);
3212 return (int)(m_vAdjust
->value
+0.5);
3215 int wxWindow::GetScrollRange( int orient
) const
3217 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3219 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3221 if (orient
== wxHORIZONTAL
)
3222 return (int)(m_hAdjust
->upper
+0.5);
3224 return (int)(m_vAdjust
->upper
+0.5);
3227 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3229 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3231 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3233 gtk_myfixed_scroll( GTK_MYFIXED(m_wxwindow
), -dx
, -dy
);
3238 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3239 gdk_gc_set_exposures( m_scrollGC, TRUE );
3242 wxNode *node = m_children.First();
3245 wxWindow *child = (wxWindow*) node->Data();
3248 child->GetSize( &sx, &sy );
3249 child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
3250 node = node->Next();
3255 GetClientSize( &cw, &ch );
3256 int w = cw - abs(dx);
3257 int h = ch - abs(dy);
3259 if ((h < 0) || (w < 0))
3267 if (dx < 0) s_x = -dx;
3268 if (dy < 0) s_y = -dy;
3271 if (dx > 0) d_x = dx;
3272 if (dy > 0) d_y = dy;
3274 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
3275 m_wxwindow->window, s_x, s_y, w, h );
3278 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3279 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3280 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3281 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
3283 Refresh( TRUE, &rect );
3288 void wxWindow::SetScrolling(bool scroll
)
3290 m_isScrolling
= g_blockEventsOnScroll
= scroll
;