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_wxwindow
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 wxPaintEvent
event( win
->GetId() );
698 event
.SetEventObject( win
);
699 win
->GetEventHandler()->ProcessEvent( event
);
701 win
->GetUpdateRegion().Clear();
704 //-----------------------------------------------------------------------------
705 // "draw" of m_wxwindow
706 //-----------------------------------------------------------------------------
708 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
711 wxapp_install_idle_handler();
716 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
717 rect
->width
, rect
->height
);
720 wxPrintf( "OnDraw from " );
721 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
722 printf( win->GetClassInfo()->GetClassName() );
723 wxPrintf( " %d %d %d %d\n", (int)rect->x,
729 wxPaintEvent
event( win
->GetId() );
730 event
.SetEventObject( win
);
731 win
->GetEventHandler()->ProcessEvent( event
);
733 win
->GetUpdateRegion().Clear();
736 //-----------------------------------------------------------------------------
737 // "key_press_event" from any window
738 //-----------------------------------------------------------------------------
740 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
743 wxapp_install_idle_handler();
745 if (!win
->m_hasVMT
) return FALSE
;
746 if (g_blockEventsOnDrag
) return FALSE
;
749 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
750 if (gdk_event->state & GDK_SHIFT_MASK)
751 printf( "ShiftDown.\n" );
753 printf( "ShiftUp.\n" );
754 if (gdk_event->state & GDK_CONTROL_MASK)
755 printf( "ControlDown.\n" );
757 printf( "ControlUp.\n" );
762 GdkModifierType state
;
763 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
765 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
767 /* sending unknown key events doesn't really make sense */
768 if (key_code
== 0) return FALSE
;
772 wxKeyEvent
event( wxEVT_KEY_DOWN
);
773 event
.SetTimestamp( gdk_event
->time
);
774 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
775 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
776 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
777 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
778 event
.m_keyCode
= key_code
;
779 event
.m_scanCode
= gdk_event
->keyval
;
782 event
.SetEventObject( win
);
783 ret
= win
->GetEventHandler()->ProcessEvent( event
);
785 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
790 wxWindow
*ancestor
= win
;
793 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
796 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
797 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
800 ancestor
= ancestor
->GetParent();
803 #endif // wxUSE_ACCEL
804 /* wxMSW doesn't send char events with Alt pressed */
805 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
806 will only be sent if it is not a menu accelerator. */
807 if ((key_code
!= 0) && ! ret
)
809 wxKeyEvent
event2( wxEVT_CHAR
);
810 event2
.SetTimestamp( gdk_event
->time
);
811 event2
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
812 event2
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
813 event2
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
814 event2
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
815 event2
.m_keyCode
= key_code
;
816 event2
.m_scanCode
= gdk_event
->keyval
;
819 event2
.SetEventObject( win
);
820 ret
= (ret
|| win
->GetEventHandler()->ProcessEvent( event2
));
823 /* win is a control: tab can be propagated up */
825 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
826 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
828 wxNavigationKeyEvent new_event
;
829 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
830 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
831 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
832 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
833 new_event
.SetCurrentFocus( win
);
834 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
837 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
839 (gdk_event
->keyval
== GDK_Escape
) )
841 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
842 new_event
.SetEventObject( win
);
843 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
846 #if (GTK_MINOR_VERSION > 0)
847 /* pressing F10 will activate the menu bar of the top frame */
849 (gdk_event
->keyval
== GDK_F10
) )
851 wxWindow
*ancestor
= win
;
854 if (wxIsKindOf(ancestor
,wxFrame
))
856 wxFrame
*frame
= (wxFrame
*) ancestor
;
857 wxMenuBar
*menubar
= frame
->GetMenuBar();
860 wxNode
*node
= menubar
->GetMenus().First();
863 // doesn't work correctly
864 // wxMenu *firstMenu = (wxMenu*) node->Data();
865 // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
871 ancestor
= ancestor
->GetParent();
877 Damn, I forgot why this didn't work, but it didn't work.
879 // win is a panel: up can be propagated to the panel
880 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
881 (gdk_event->keyval == GDK_Up))
883 win->m_parent->SetFocus();
887 // win is a panel: left/right can be propagated to the panel
888 if ((!ret) && (win->m_wxwindow) &&
889 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
890 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
892 wxNavigationKeyEvent new_event;
893 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
894 new_event.SetCurrentFocus( win );
895 ret = win->GetEventHandler()->ProcessEvent( new_event );
901 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
908 //-----------------------------------------------------------------------------
909 // "key_release_event" from any window
910 //-----------------------------------------------------------------------------
912 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
915 wxapp_install_idle_handler();
917 if (!win
->m_hasVMT
) return FALSE
;
918 if (g_blockEventsOnDrag
) return FALSE
;
921 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
922 if (gdk_event->state & GDK_SHIFT_MASK)
923 printf( "ShiftDown.\n" );
925 printf( "ShiftUp.\n" );
926 if (gdk_event->state & GDK_CONTROL_MASK)
927 printf( "ControlDown.\n" );
929 printf( "ControlUp.\n" );
933 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
935 /* sending unknown key events doesn't really make sense */
936 if (key_code
== 0) return FALSE
;
940 GdkModifierType state
;
941 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
943 wxKeyEvent
event( wxEVT_KEY_UP
);
944 event
.SetTimestamp( gdk_event
->time
);
945 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
946 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
947 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
948 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
949 event
.m_keyCode
= key_code
;
950 event
.m_scanCode
= gdk_event
->keyval
;
953 event
.SetEventObject( win
);
955 if (win
->GetEventHandler()->ProcessEvent( event
))
957 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
964 //-----------------------------------------------------------------------------
965 // "button_press_event"
966 //-----------------------------------------------------------------------------
968 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
971 wxapp_install_idle_handler();
974 wxPrintf( wxT("1) OnButtonPress from ") );
975 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
976 wxPrintf( win->GetClassInfo()->GetClassName() );
977 wxPrintf( wxT(".\n") );
979 if (!win
->m_hasVMT
) return FALSE
;
980 if (g_blockEventsOnDrag
) return TRUE
;
981 if (g_blockEventsOnScroll
) return TRUE
;
983 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
987 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
989 gtk_widget_grab_focus (win
->m_wxwindow
);
992 wxPrintf( wxT("GrabFocus from ") );
993 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
994 wxPrintf( win->GetClassInfo()->GetClassName() );
995 wxPrintf( wxT(".\n") );
1002 wxPrintf( wxT("2) OnButtonPress from ") );
1003 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1004 wxPrintf( win->GetClassInfo()->GetClassName() );
1005 wxPrintf( wxT(".\n") );
1008 wxEventType event_type
= wxEVT_LEFT_DOWN
;
1010 if (gdk_event
->button
== 1)
1012 switch (gdk_event
->type
)
1014 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
1015 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
1019 else if (gdk_event
->button
== 2)
1021 switch (gdk_event
->type
)
1023 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
1024 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
1028 else if (gdk_event
->button
== 3)
1030 switch (gdk_event
->type
)
1032 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
1033 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
1038 wxMouseEvent
event( event_type
);
1039 event
.SetTimestamp( gdk_event
->time
);
1040 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1041 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1042 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1043 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1044 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1045 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1046 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1048 event
.m_x
= (long)gdk_event
->x
;
1049 event
.m_y
= (long)gdk_event
->y
;
1051 // Some control don't have their own X window and thus cannot get
1054 if (!g_captureWindow
)
1056 wxNode
*node
= win
->GetChildren().First();
1059 wxWindow
*child
= (wxWindow
*)node
->Data();
1061 if (child
->m_isStaticBox
)
1063 // wxStaticBox is transparent in the box itself
1066 int xx1
= child
->m_x
;
1067 int yy1
= child
->m_y
;
1068 int xx2
= child
->m_x
+ child
->m_width
;
1069 int yy2
= child
->m_x
+ child
->m_height
;
1072 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1074 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1076 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1078 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1081 event
.m_x
-= child
->m_x
;
1082 event
.m_y
-= child
->m_y
;
1089 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1090 (child
->m_x
<= event
.m_x
) &&
1091 (child
->m_y
<= event
.m_y
) &&
1092 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1093 (child
->m_y
+child
->m_height
>= event
.m_y
))
1096 event
.m_x
-= child
->m_x
;
1097 event
.m_y
-= child
->m_y
;
1101 node
= node
->Next();
1105 event
.SetEventObject( win
);
1107 gs_timeLastClick
= gdk_event
->time
;
1109 if (win
->GetEventHandler()->ProcessEvent( event
))
1111 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
1118 //-----------------------------------------------------------------------------
1119 // "button_release_event"
1120 //-----------------------------------------------------------------------------
1122 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1125 wxapp_install_idle_handler();
1127 if (!win
->m_hasVMT
) return FALSE
;
1128 if (g_blockEventsOnDrag
) return FALSE
;
1129 if (g_blockEventsOnScroll
) return FALSE
;
1131 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1134 printf( "OnButtonRelease from " );
1135 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1136 printf( win->GetClassInfo()->GetClassName() );
1140 wxEventType event_type
= wxEVT_NULL
;
1142 switch (gdk_event
->button
)
1144 case 1: event_type
= wxEVT_LEFT_UP
; break;
1145 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
1146 case 3: event_type
= wxEVT_RIGHT_UP
; break;
1149 wxMouseEvent
event( event_type
);
1150 event
.SetTimestamp( gdk_event
->time
);
1151 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1152 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1153 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1154 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1155 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1156 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1157 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1158 event
.m_x
= (long)gdk_event
->x
;
1159 event
.m_y
= (long)gdk_event
->y
;
1161 // Some control don't have their own X window and thus cannot get
1164 if (!g_captureWindow
)
1166 wxNode
*node
= win
->GetChildren().First();
1169 wxWindow
*child
= (wxWindow
*)node
->Data();
1171 if (child
->m_isStaticBox
)
1173 // wxStaticBox is transparent in the box itself
1176 int xx1
= child
->m_x
;
1177 int yy1
= child
->m_y
;
1178 int xx2
= child
->m_x
+ child
->m_width
;
1179 int yy2
= child
->m_x
+ child
->m_height
;
1182 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1184 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1186 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1188 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1191 event
.m_x
-= child
->m_x
;
1192 event
.m_y
-= child
->m_y
;
1199 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1200 (child
->m_x
<= event
.m_x
) &&
1201 (child
->m_y
<= event
.m_y
) &&
1202 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1203 (child
->m_y
+child
->m_height
>= event
.m_y
))
1206 event
.m_x
-= child
->m_x
;
1207 event
.m_y
-= child
->m_y
;
1211 node
= node
->Next();
1215 event
.SetEventObject( win
);
1217 if (win
->GetEventHandler()->ProcessEvent( event
))
1219 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1226 //-----------------------------------------------------------------------------
1227 // "motion_notify_event"
1228 //-----------------------------------------------------------------------------
1230 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1233 wxapp_install_idle_handler();
1235 if (!win
->m_hasVMT
) return FALSE
;
1236 if (g_blockEventsOnDrag
) return FALSE
;
1237 if (g_blockEventsOnScroll
) return FALSE
;
1239 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1241 if (gdk_event
->is_hint
)
1245 GdkModifierType state
;
1246 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1252 printf( "OnMotion from " );
1253 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1254 printf( win->GetClassInfo()->GetClassName() );
1258 wxMouseEvent
event( wxEVT_MOTION
);
1259 event
.SetTimestamp( gdk_event
->time
);
1260 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1261 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1262 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1263 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1264 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1265 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1266 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1268 event
.m_x
= (long)gdk_event
->x
;
1269 event
.m_y
= (long)gdk_event
->y
;
1271 // Some control don't have their own X window and thus cannot get
1274 if (!g_captureWindow
)
1276 wxNode
*node
= win
->GetChildren().First();
1279 wxWindow
*child
= (wxWindow
*)node
->Data();
1281 if (child
->m_isStaticBox
)
1283 // wxStaticBox is transparent in the box itself
1286 int xx1
= child
->m_x
;
1287 int yy1
= child
->m_y
;
1288 int xx2
= child
->m_x
+ child
->m_width
;
1289 int yy2
= child
->m_x
+ child
->m_height
;
1292 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1294 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1296 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1298 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1301 event
.m_x
-= child
->m_x
;
1302 event
.m_y
-= child
->m_y
;
1309 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1310 (child
->m_x
<= event
.m_x
) &&
1311 (child
->m_y
<= event
.m_y
) &&
1312 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1313 (child
->m_y
+child
->m_height
>= event
.m_y
))
1316 event
.m_x
-= child
->m_x
;
1317 event
.m_y
-= child
->m_y
;
1321 node
= node
->Next();
1325 event
.SetEventObject( win
);
1327 if (win
->GetEventHandler()->ProcessEvent( event
))
1329 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1336 //-----------------------------------------------------------------------------
1338 //-----------------------------------------------------------------------------
1340 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1343 wxapp_install_idle_handler();
1345 if (!win
->m_hasVMT
) return FALSE
;
1346 if (g_blockEventsOnDrag
) return FALSE
;
1348 g_focusWindow
= win
;
1350 if (win
->m_wxwindow
)
1352 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1354 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1356 printf( "SetFocus flag from " );
1357 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1358 printf( win->GetClassInfo()->GetClassName() );
1366 printf( "OnSetFocus from " );
1367 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1368 printf( win->GetClassInfo()->GetClassName() );
1370 printf( WXSTRINGCAST win->GetLabel() );
1374 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1375 event
.SetEventObject( win
);
1377 if (win
->GetEventHandler()->ProcessEvent( event
))
1379 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1386 //-----------------------------------------------------------------------------
1387 // "focus_out_event"
1388 //-----------------------------------------------------------------------------
1390 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1393 wxapp_install_idle_handler();
1395 if (!win
->m_hasVMT
) return FALSE
;
1396 if (g_blockEventsOnDrag
) return FALSE
;
1398 if (win
->m_wxwindow
)
1400 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1401 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1405 printf( "OnKillFocus from " );
1406 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1407 printf( win->GetClassInfo()->GetClassName() );
1411 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1412 event
.SetEventObject( win
);
1414 if (win
->GetEventHandler()->ProcessEvent( event
))
1416 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1423 //-----------------------------------------------------------------------------
1424 // "enter_notify_event"
1425 //-----------------------------------------------------------------------------
1427 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1430 wxapp_install_idle_handler();
1432 if (!win
->m_hasVMT
) return FALSE
;
1433 if (g_blockEventsOnDrag
) return FALSE
;
1435 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1437 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1438 #if (GTK_MINOR_VERSION > 0)
1439 event
.SetTimestamp( gdk_event
->time
);
1441 event
.SetEventObject( win
);
1445 GdkModifierType state
= (GdkModifierType
)0;
1447 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1449 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1450 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1451 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1452 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1453 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1454 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1455 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1457 event
.m_x
= (long)x
;
1458 event
.m_y
= (long)y
;
1460 if (win
->GetEventHandler()->ProcessEvent( event
))
1462 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1469 //-----------------------------------------------------------------------------
1470 // "leave_notify_event"
1471 //-----------------------------------------------------------------------------
1473 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1476 wxapp_install_idle_handler();
1478 if (!win
->m_hasVMT
) return FALSE
;
1479 if (g_blockEventsOnDrag
) return FALSE
;
1481 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1483 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1484 #if (GTK_MINOR_VERSION > 0)
1485 event
.SetTimestamp( gdk_event
->time
);
1487 event
.SetEventObject( win
);
1491 GdkModifierType state
= (GdkModifierType
)0;
1493 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1495 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1496 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1497 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1498 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1499 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1500 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1501 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1503 event
.m_x
= (long)x
;
1504 event
.m_y
= (long)y
;
1506 if (win
->GetEventHandler()->ProcessEvent( event
))
1508 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1515 //-----------------------------------------------------------------------------
1516 // "value_changed" from m_vAdjust
1517 //-----------------------------------------------------------------------------
1519 static void gtk_window_vscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1522 wxapp_install_idle_handler();
1524 if (g_blockEventsOnDrag
) return;
1526 if (!win
->m_hasVMT
) return;
1528 float diff
= adjust
->value
- win
->m_oldVerticalPos
;
1529 if (fabs(diff
) < 0.2) return;
1531 win
->m_oldVerticalPos
= adjust
->value
;
1533 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1534 GtkRange
*range
= GTK_RANGE( scrolledWindow
->vscrollbar
);
1536 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1537 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1538 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1539 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1540 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1542 int value
= (int)(adjust
->value
+0.5);
1544 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1545 event
.SetEventObject( win
);
1546 win
->GetEventHandler()->ProcessEvent( event
);
1549 //-----------------------------------------------------------------------------
1550 // "value_changed" from m_hAdjust
1551 //-----------------------------------------------------------------------------
1553 static void gtk_window_hscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1556 wxapp_install_idle_handler();
1558 if (g_blockEventsOnDrag
) return;
1559 if (!win
->m_hasVMT
) return;
1561 float diff
= adjust
->value
- win
->m_oldHorizontalPos
;
1562 if (fabs(diff
) < 0.2) return;
1564 win
->m_oldHorizontalPos
= adjust
->value
;
1566 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1567 GtkRange
*range
= GTK_RANGE( scrolledWindow
->hscrollbar
);
1569 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1570 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1571 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1572 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1573 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1575 int value
= (int)(adjust
->value
+0.5);
1577 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1578 event
.SetEventObject( win
);
1579 win
->GetEventHandler()->ProcessEvent( event
);
1582 //-----------------------------------------------------------------------------
1583 // "changed" from m_vAdjust
1584 //-----------------------------------------------------------------------------
1586 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1589 wxapp_install_idle_handler();
1591 if (g_blockEventsOnDrag
) return;
1592 if (!win
->m_hasVMT
) return;
1594 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1595 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1597 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1598 event
.SetEventObject( win
);
1599 win
->GetEventHandler()->ProcessEvent( event
);
1602 //-----------------------------------------------------------------------------
1603 // "changed" from m_hAdjust
1604 //-----------------------------------------------------------------------------
1606 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1609 wxapp_install_idle_handler();
1611 if (g_blockEventsOnDrag
) return;
1612 if (!win
->m_hasVMT
) return;
1614 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1615 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1617 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1618 event
.SetEventObject( win
);
1619 win
->GetEventHandler()->ProcessEvent( event
);
1622 //-----------------------------------------------------------------------------
1623 // "button_press_event" from scrollbar
1624 //-----------------------------------------------------------------------------
1626 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1627 GdkEventButton
*WXUNUSED(gdk_event
),
1631 wxapp_install_idle_handler();
1633 // don't test here as we can release the mouse while being over
1634 // a different window than the slider
1636 // if (gdk_event->window != widget->slider) return FALSE;
1638 win
->SetScrolling( TRUE
);
1643 //-----------------------------------------------------------------------------
1644 // "button_release_event" from scrollbar
1645 //-----------------------------------------------------------------------------
1647 static gint
gtk_scrollbar_button_release_callback( GtkRange
*WXUNUSED(widget
),
1648 GdkEventButton
*WXUNUSED(gdk_event
),
1652 // don't test here as we can release the mouse while being over
1653 // a different window than the slider
1655 // if (gdk_event->window != widget->slider) return FALSE;
1657 win
->SetScrolling( FALSE
);
1662 // ----------------------------------------------------------------------------
1663 // this wxWindowBase function is implemented here (in platform-specific file)
1664 // because it is static and so couldn't be made virtual
1665 // ----------------------------------------------------------------------------
1667 wxWindow
*wxWindowBase::FindFocus()
1669 return g_focusWindow
;
1672 //-----------------------------------------------------------------------------
1673 // "realize" from m_widget
1674 //-----------------------------------------------------------------------------
1676 /* we cannot set colours and fonts before the widget has
1677 been realized, so we do this directly after realization */
1680 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1683 wxapp_install_idle_handler();
1685 if (win
->m_delayedFont
)
1686 win
->SetFont( win
->GetFont() );
1688 if (win
->m_delayedBackgroundColour
)
1689 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1691 if (win
->m_delayedForegroundColour
)
1692 win
->SetForegroundColour( win
->GetForegroundColour() );
1694 wxWindowCreateEvent
event( win
);
1695 event
.SetEventObject( win
);
1696 win
->GetEventHandler()->ProcessEvent( event
);
1701 //-----------------------------------------------------------------------------
1702 // InsertChild for wxWindow.
1703 //-----------------------------------------------------------------------------
1705 /* Callback for wxWindow. This very strange beast has to be used because
1706 * C++ has no virtual methods in a constructor. We have to emulate a
1707 * virtual function here as wxNotebook requires a different way to insert
1708 * a child in it. I had opted for creating a wxNotebookPage window class
1709 * which would have made this superfluous (such in the MDI window system),
1710 * but no-one was listening to me... */
1712 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1714 /* the window might have been scrolled already, do we
1715 have to adapt the position */
1716 GtkMyFixed
*myfixed
= GTK_MYFIXED(parent
->m_wxwindow
);
1717 child
->m_x
+= myfixed
->xoffset
;
1718 child
->m_y
+= myfixed
->yoffset
;
1720 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1721 GTK_WIDGET(child
->m_widget
),
1727 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1729 /* we now allow a window to get the focus as long as it
1730 doesn't have any children. */
1731 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1735 //-----------------------------------------------------------------------------
1737 //-----------------------------------------------------------------------------
1739 wxWindow
* wxGetActiveWindow()
1741 return g_focusWindow
;
1744 //-----------------------------------------------------------------------------
1746 //-----------------------------------------------------------------------------
1748 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1750 void wxWindow::Init()
1756 m_widget
= (GtkWidget
*) NULL
;
1757 m_wxwindow
= (GtkWidget
*) NULL
;
1767 m_needParent
= TRUE
;
1768 m_isBeingDeleted
= FALSE
;
1770 m_hasScrolling
= FALSE
;
1771 m_isScrolling
= FALSE
;
1773 m_hAdjust
= (GtkAdjustment
*) NULL
;
1774 m_vAdjust
= (GtkAdjustment
*) NULL
;
1775 m_oldHorizontalPos
= 0.0;
1776 m_oldVerticalPos
= 0.0;
1779 m_scrollGC
= (GdkGC
*) NULL
;
1780 m_widgetStyle
= (GtkStyle
*) NULL
;
1782 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1784 m_isStaticBox
= FALSE
;
1785 m_isRadioButton
= FALSE
;
1786 m_acceptsFocus
= FALSE
;
1788 m_cursor
= *wxSTANDARD_CURSOR
;
1791 wxWindow::wxWindow()
1796 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1797 const wxPoint
&pos
, const wxSize
&size
,
1798 long style
, const wxString
&name
)
1802 Create( parent
, id
, pos
, size
, style
, name
);
1805 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1806 const wxPoint
&pos
, const wxSize
&size
,
1807 long style
, const wxString
&name
)
1809 if (!PreCreation( parent
, pos
, size
) ||
1810 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
1812 wxFAIL_MSG( wxT("wxWindow creation failed") );
1816 m_insertCallback
= wxInsertChildInWindow
;
1818 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1819 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1822 debug_focus_in( m_widget
, wxT("wxWindow::m_widget"), name
);
1825 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1828 debug_focus_in( scrolledWindow
->hscrollbar
, wxT("wxWindow::hsrcollbar"), name
);
1829 debug_focus_in( scrolledWindow
->vscrollbar
, wxT("wxWindow::vsrcollbar"), name
);
1832 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1833 scroll_class
->scrollbar_spacing
= 0;
1835 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1837 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1838 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1840 m_wxwindow
= gtk_myfixed_new();
1843 debug_focus_in( m_wxwindow
, wxT("wxWindow::m_wxwindow"), name
);
1846 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1848 #if (GTK_MINOR_VERSION > 0)
1849 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1851 if (HasFlag(wxRAISED_BORDER
))
1853 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_OUT
);
1855 else if (HasFlag(wxSUNKEN_BORDER
))
1857 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_IN
);
1859 else if (HasFlag(wxSIMPLE_BORDER
))
1861 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_THIN
);
1865 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_NONE
);
1867 #else // GTK_MINOR_VERSION == 0
1868 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1870 if (HasFlag(wxRAISED_BORDER
))
1872 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1874 else if (HasFlag(wxSUNKEN_BORDER
))
1876 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1880 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1882 #endif // GTK_MINOR_VERSION
1884 if (HasFlag(wxTAB_TRAVERSAL
))
1886 /* we now allow a window to get the focus as long as it
1887 doesn't have any children. */
1888 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1889 m_acceptsFocus
= FALSE
;
1893 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1894 m_acceptsFocus
= TRUE
;
1897 #if (GTK_MINOR_VERSION == 0)
1898 // shut the viewport up
1899 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1900 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1901 #endif // GTK_MINOR_VERSION == 0
1903 // I _really_ don't want scrollbars in the beginning
1904 m_vAdjust
->lower
= 0.0;
1905 m_vAdjust
->upper
= 1.0;
1906 m_vAdjust
->value
= 0.0;
1907 m_vAdjust
->step_increment
= 1.0;
1908 m_vAdjust
->page_increment
= 1.0;
1909 m_vAdjust
->page_size
= 5.0;
1910 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1911 m_hAdjust
->lower
= 0.0;
1912 m_hAdjust
->upper
= 1.0;
1913 m_hAdjust
->value
= 0.0;
1914 m_hAdjust
->step_increment
= 1.0;
1915 m_hAdjust
->page_increment
= 1.0;
1916 m_hAdjust
->page_size
= 5.0;
1917 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1919 // these handlers block mouse events to any window during scrolling such as
1920 // motion events and prevent GTK and wxWindows from fighting over where the
1923 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1924 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1926 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1927 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1929 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1930 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1932 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1933 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1935 // these handlers get notified when screen updates are required either when
1936 // scrolling or when the window size (and therefore scrollbar configuration)
1939 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1940 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1941 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1942 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1944 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1945 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1946 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1947 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1949 gtk_widget_show( m_wxwindow
);
1952 m_parent
->DoAddChild( this );
1961 wxWindow::~wxWindow()
1963 m_isBeingDeleted
= TRUE
;
1972 m_parent
->RemoveChild( this );
1976 gtk_style_unref( m_widgetStyle
);
1977 m_widgetStyle
= (GtkStyle
*) NULL
;
1982 gdk_gc_unref( m_scrollGC
);
1983 m_scrollGC
= (GdkGC
*) NULL
;
1988 gtk_widget_destroy( m_wxwindow
);
1989 m_wxwindow
= (GtkWidget
*) NULL
;
1994 gtk_widget_destroy( m_widget
);
1995 m_widget
= (GtkWidget
*) NULL
;
1999 bool wxWindow::PreCreation( wxWindow
*parent
, const wxPoint
&pos
, const wxSize
&size
)
2001 wxCHECK_MSG( !m_needParent
|| parent
, FALSE
, wxT("Need complete parent.") );
2003 /* this turns -1 into 20 so that a minimal window is
2004 visible even although -1,-1 has been given as the
2005 size of the window. the same trick is used in other
2006 ports and should make debugging easier */
2007 m_width
= WidthDefault(size
.x
);
2008 m_height
= HeightDefault(size
.y
);
2013 /* some reasonable defaults */
2018 m_x
= (gdk_screen_width () - m_width
) / 2;
2019 if (m_x
< 10) m_x
= 10;
2023 m_y
= (gdk_screen_height () - m_height
) / 2;
2024 if (m_y
< 10) m_y
= 10;
2031 void wxWindow::PostCreation()
2033 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2037 /* these get reported to wxWindows -> wxPaintEvent */
2038 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
2039 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
2041 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
2042 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
2044 #if (GTK_MINOR_VERSION > 0)
2045 /* these are called when the "sunken" or "raised" borders are drawn */
2046 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
2047 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
2049 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
2050 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
2054 GtkWidget
*connect_widget
= GetConnectWidget();
2056 ConnectWidget( connect_widget
);
2058 /* we cannot set colours, fonts and cursors before the widget has
2059 been realized, so we do this directly after realization */
2060 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
2061 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
2066 void wxWindow::ConnectWidget( GtkWidget
*widget
)
2068 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
2069 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
2071 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
2072 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
2074 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
2075 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
2077 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
2078 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
2080 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
2081 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
2083 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
2084 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2086 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
2087 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2089 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
2090 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
2092 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
2093 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
2096 bool wxWindow::Destroy()
2098 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2102 return wxWindowBase::Destroy();
2105 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
2107 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2108 wxASSERT_MSG( (m_parent
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") );
2110 if (m_resizing
) return; /* I don't like recursions */
2113 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
2115 /* don't set the size for children of wxNotebook, just take the values. */
2123 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_parent
->m_wxwindow
);
2125 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
2127 if (x
!= -1) m_x
= x
+ myfixed
->xoffset
;
2128 if (y
!= -1) m_y
= y
+ myfixed
->yoffset
;
2129 if (width
!= -1) m_width
= width
;
2130 if (height
!= -1) m_height
= height
;
2134 m_x
= x
+ myfixed
->xoffset
;
2135 m_y
= y
+ myfixed
->yoffset
;
2140 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2142 if (width
== -1) m_width
= 80;
2145 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2147 if (height
== -1) m_height
= 26;
2150 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2151 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2152 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2153 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2156 int bottom_border
= 0;
2158 if (GTK_WIDGET_CAN_DEFAULT(m_widget
))
2160 /* the default button has a border around it */
2165 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
2170 m_height
+border
+bottom_border
);
2175 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2176 event
.SetEventObject( this );
2177 GetEventHandler()->ProcessEvent( event
);
2182 void wxWindow::OnInternalIdle()
2184 wxCursor cursor
= m_cursor
;
2185 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2189 /* I now set the cursor the anew in every OnInternalIdle call
2190 as setting the cursor in a parent window also effects the
2191 windows above so that checking for the current cursor is
2196 GdkWindow
*window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2198 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2200 if (!g_globalCursor
.Ok())
2201 cursor
= *wxSTANDARD_CURSOR
;
2203 window
= m_widget
->window
;
2204 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2205 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2211 GdkWindow
*window
= m_widget
->window
;
2212 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2213 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2221 void wxWindow::DoGetSize( int *width
, int *height
) const
2223 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2225 if (width
) (*width
) = m_width
;
2226 if (height
) (*height
) = m_height
;
2229 void wxWindow::DoSetClientSize( int width
, int height
)
2231 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2235 SetSize( width
, height
);
2242 #if (GTK_MINOR_VERSION == 0)
2243 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2247 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2248 #if 0 // unused - if this is ok, just remove this line (VZ)
2249 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2252 GtkWidget
*viewport
= scroll_window
->viewport
;
2253 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2255 dw
+= 2 * viewport_class
->xthickness
;
2256 dh
+= 2 * viewport_class
->ythickness
;
2260 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2262 /* when using GTK 1.2 we set the shadow border size to 2 */
2266 if (HasFlag(wxSIMPLE_BORDER
))
2268 /* when using GTK 1.2 we set the simple border size to 1 */
2277 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2278 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2280 we use this instead: range.slider_width = 11 + 2*2pts edge
2283 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2284 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2286 if (scroll_window
->vscrollbar_visible
)
2288 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2289 dw
+= scroll_class
->scrollbar_spacing
;
2292 if (scroll_window
->hscrollbar_visible
)
2294 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2295 dh
+= scroll_class
->scrollbar_spacing
;
2299 SetSize( width
+dw
, height
+dh
);
2303 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2305 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2309 if (width
) (*width
) = m_width
;
2310 if (height
) (*height
) = m_height
;
2317 #if (GTK_MINOR_VERSION == 0)
2318 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2322 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2323 #if 0 // unused - if this is ok, just remove this line (VZ)
2324 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2327 GtkWidget
*viewport
= scroll_window
->viewport
;
2328 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2330 dw
+= 2 * viewport_class
->xthickness
;
2331 dh
+= 2 * viewport_class
->ythickness
;
2335 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2337 /* when using GTK 1.2 we set the shadow border size to 2 */
2341 if (HasFlag(wxSIMPLE_BORDER
))
2343 /* when using GTK 1.2 we set the simple border size to 1 */
2351 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2352 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2354 we use this instead: range.slider_width = 11 + 2*2pts edge
2357 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2358 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2360 if (scroll_window
->vscrollbar_visible
)
2362 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2363 dw
+= scroll_class
->scrollbar_spacing
;
2366 if (scroll_window
->hscrollbar_visible
)
2368 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2369 dh
+= scroll_class
->scrollbar_spacing
;
2373 if (width
) (*width
) = m_width
- dw
;
2374 if (height
) (*height
) = m_height
- dh
;
2378 void wxWindow::DoGetPosition( int *x
, int *y
) const
2380 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2384 if (m_parent
&& m_parent
->m_wxwindow
)
2386 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_parent
->m_wxwindow
);
2387 dx
= myfixed
->xoffset
;
2388 dy
= myfixed
->yoffset
;
2391 if (x
) (*x
) = m_x
- dx
;
2392 if (y
) (*y
) = m_y
- dy
;
2395 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2397 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2399 if (!m_widget
->window
) return;
2401 GdkWindow
*source
= (GdkWindow
*) NULL
;
2403 source
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2405 source
= m_widget
->window
;
2409 gdk_window_get_origin( source
, &org_x
, &org_y
);
2413 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2415 org_x
+= m_widget
->allocation
.x
;
2416 org_y
+= m_widget
->allocation
.y
;
2424 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2426 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2428 if (!m_widget
->window
) return;
2430 GdkWindow
*source
= (GdkWindow
*) NULL
;
2432 source
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2434 source
= m_widget
->window
;
2438 gdk_window_get_origin( source
, &org_x
, &org_y
);
2442 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2444 org_x
+= m_widget
->allocation
.x
;
2445 org_y
+= m_widget
->allocation
.y
;
2453 bool wxWindow::Show( bool show
)
2455 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2457 if (!wxWindowBase::Show(show
))
2464 gtk_widget_show( m_widget
);
2466 gtk_widget_hide( m_widget
);
2471 bool wxWindow::Enable( bool enable
)
2473 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2475 if (!wxWindowBase::Enable(enable
))
2481 gtk_widget_set_sensitive( m_widget
, enable
);
2483 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2488 int wxWindow::GetCharHeight() const
2490 wxCHECK_MSG( (m_widget
!= NULL
), 12, wxT("invalid window") );
2492 wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") );
2494 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2496 return font
->ascent
+ font
->descent
;
2499 int wxWindow::GetCharWidth() const
2501 wxCHECK_MSG( (m_widget
!= NULL
), 8, wxT("invalid window") );
2503 wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") );
2505 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2507 return gdk_string_width( font
, "H" );
2510 void wxWindow::GetTextExtent( const wxString
& string
,
2514 int *externalLeading
,
2515 const wxFont
*theFont
) const
2517 wxFont fontToUse
= m_font
;
2518 if (theFont
) fontToUse
= *theFont
;
2520 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
2522 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2523 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2524 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2525 if (descent
) (*descent
) = font
->descent
;
2526 if (externalLeading
) (*externalLeading
) = 0; // ??
2529 void wxWindow::SetFocus()
2531 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2533 GtkWidget
*connect_widget
= GetConnectWidget();
2536 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2538 gtk_widget_grab_focus (connect_widget
);
2540 else if (GTK_IS_CONTAINER(connect_widget
))
2542 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2550 bool wxWindow::AcceptsFocus() const
2552 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2555 bool wxWindow::Reparent( wxWindowBase
*newParentBase
)
2557 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2559 wxWindow
*oldParent
= m_parent
,
2560 *newParent
= (wxWindow
*)newParentBase
;
2562 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2564 if ( !wxWindowBase::Reparent(newParent
) )
2567 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2569 /* prevent GTK from deleting the widget arbitrarily */
2570 gtk_widget_ref( m_widget
);
2574 gtk_container_remove( GTK_CONTAINER(oldParent
->m_wxwindow
), m_widget
);
2577 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2581 /* insert GTK representation */
2582 (*(newParent
->m_insertCallback
))(newParent
, this);
2585 /* reverse: prevent GTK from deleting the widget arbitrarily */
2586 gtk_widget_unref( m_widget
);
2591 void wxWindow::DoAddChild(wxWindow
*child
)
2593 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2595 wxASSERT_MSG( (child
!= NULL
), wxT("invalid child window") );
2597 wxASSERT_MSG( (m_insertCallback
!= NULL
), wxT("invalid child insertion function") );
2602 /* insert GTK representation */
2603 (*m_insertCallback
)(this, child
);
2606 void wxWindow::Raise()
2608 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2610 if (!m_widget
->window
) return;
2612 gdk_window_raise( m_widget
->window
);
2615 void wxWindow::Lower()
2617 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2619 if (!m_widget
->window
) return;
2621 gdk_window_lower( m_widget
->window
);
2624 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2626 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2628 return wxWindowBase::SetCursor( cursor
);
2631 void wxWindow::WarpPointer( int x
, int y
)
2633 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2635 /* we provide this function ourselves as it is
2636 missing in GDK (top of this file) */
2638 GdkWindow
*window
= (GdkWindow
*) NULL
;
2640 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2642 window
= GetConnectWidget()->window
;
2645 gdk_window_warp_pointer( window
, x
, y
);
2648 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2650 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2652 if (!m_widget
->window
) return;
2654 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2658 gdk_window_clear_area( GTK_MYFIXED(m_wxwindow
)->bin_window
,
2660 rect
->width
, rect
->height
);
2664 gdk_window_clear( GTK_MYFIXED(m_wxwindow
)->bin_window
);
2672 /* call the callback directly for preventing GTK from
2673 clearing the background */
2676 GetClientSize( &w
, &h
);
2678 GetUpdateRegion().Union( 0, 0, w
, h
);
2679 wxPaintEvent
event( GetId() );
2680 event
.SetEventObject( this );
2681 GetEventHandler()->ProcessEvent( event
);
2682 GetUpdateRegion().Clear();
2686 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2694 /* call the callback directly for preventing GTK from
2695 clearing the background */
2696 GetUpdateRegion().Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
2697 wxPaintEvent
event( GetId() );
2698 event
.SetEventObject( this );
2699 GetEventHandler()->ProcessEvent( event
);
2700 GetUpdateRegion().Clear();
2704 GdkRectangle gdk_rect
;
2705 gdk_rect
.x
= rect
->x
;
2706 gdk_rect
.y
= rect
->y
;
2707 gdk_rect
.width
= rect
->width
;
2708 gdk_rect
.height
= rect
->height
;
2710 gtk_widget_draw( m_widget
, &gdk_rect
);
2715 void wxWindow::Clear()
2717 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2719 if (!m_widget
->window
) return;
2721 if (m_wxwindow
&& m_wxwindow
->window
)
2723 gdk_window_clear( m_wxwindow
->window
);
2728 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2730 wxWindowBase::DoSetToolTip(tip
);
2733 m_tooltip
->Apply( this );
2736 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2738 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2740 #endif // wxUSE_TOOLTIPS
2742 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2744 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2746 if (!wxWindowBase::SetBackgroundColour(colour
))
2748 // don't leave if the GTK widget has just
2750 if (!m_delayedBackgroundColour
) return FALSE
;
2753 GdkWindow
*window
= (GdkWindow
*) NULL
;
2755 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2757 window
= GetConnectWidget()->window
;
2761 // indicate that a new style has been set
2762 // but it couldn't get applied as the
2763 // widget hasn't been realized yet.
2764 m_delayedBackgroundColour
= TRUE
;
2766 // pretend we have done something
2772 /* wxMSW doesn't clear the window here. I don't do that either to
2773 provide compatibility. call Clear() to do the job. */
2775 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2776 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2779 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2780 if (sysbg
== m_backgroundColour
)
2782 m_backgroundColour
= wxNullColour
;
2784 m_backgroundColour
= sysbg
;
2794 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2796 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2798 if (!wxWindowBase::SetForegroundColour(colour
))
2800 // don't leave if the GTK widget has just
2802 if (!m_delayedForegroundColour
) return FALSE
;
2805 GdkWindow
*window
= (GdkWindow
*) NULL
;
2807 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2809 window
= GetConnectWidget()->window
;
2813 // indicate that a new style has been set
2814 // but it couldn't get applied as the
2815 // widget hasn't been realized yet.
2816 m_delayedForegroundColour
= TRUE
;
2818 // pretend we have done something
2822 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2823 if ( sysbg
== m_backgroundColour
)
2825 m_backgroundColour
= wxNullColour
;
2827 m_backgroundColour
= sysbg
;
2837 GtkStyle
*wxWindow::GetWidgetStyle()
2839 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2841 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2843 return m_widgetStyle
;
2846 void wxWindow::SetWidgetStyle()
2848 GtkStyle
*style
= GetWidgetStyle();
2850 gdk_font_unref( style
->font
);
2851 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2853 if (m_foregroundColour
.Ok())
2855 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2856 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2857 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2858 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2861 if (m_backgroundColour
.Ok())
2863 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2864 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2865 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2866 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2867 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2868 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2869 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2870 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2871 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2875 void wxWindow::ApplyWidgetStyle()
2879 //-----------------------------------------------------------------------------
2880 // Pop-up menu stuff
2881 //-----------------------------------------------------------------------------
2883 static void gtk_pop_hide_callback( GtkWidget
*WXUNUSED(widget
), bool* is_waiting
)
2885 *is_waiting
= FALSE
;
2888 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2890 menu
->SetInvokingWindow( win
);
2891 wxNode
*node
= menu
->GetItems().First();
2894 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2895 if (menuitem
->IsSubMenu())
2897 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2899 node
= node
->Next();
2903 static gint gs_pop_x
= 0;
2904 static gint gs_pop_y
= 0;
2906 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2910 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2915 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
2917 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2919 wxCHECK_MSG( menu
!= NULL
, FALSE
, wxT("invalid popup-menu") );
2921 SetInvokingWindow( menu
, this );
2928 bool is_waiting
= TRUE
;
2930 gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide",
2931 GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting
);
2934 GTK_MENU(menu
->m_menu
),
2935 (GtkWidget
*) NULL
, // parent menu shell
2936 (GtkWidget
*) NULL
, // parent menu item
2937 (GtkMenuPositionFunc
) pop_pos_callback
,
2938 (gpointer
) this, // client data
2939 0, // button used to activate it
2940 0 //gs_timeLastClick // the time of activation
2945 while (gtk_events_pending())
2946 gtk_main_iteration();
2952 #if wxUSE_DRAG_AND_DROP
2954 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2956 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2958 GtkWidget
*dnd_widget
= GetConnectWidget();
2960 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2962 if (m_dropTarget
) delete m_dropTarget
;
2963 m_dropTarget
= dropTarget
;
2965 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2968 #endif // wxUSE_DRAG_AND_DROP
2970 GtkWidget
* wxWindow::GetConnectWidget()
2972 GtkWidget
*connect_widget
= m_widget
;
2973 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2975 return connect_widget
;
2978 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2981 return (window
== GTK_MYFIXED(m_wxwindow
)->bin_window
);
2983 return (window
== m_widget
->window
);
2986 bool wxWindow::SetFont( const wxFont
&font
)
2988 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2990 if (!wxWindowBase::SetFont(font
))
2992 // don't leave if the GTK widget has just
2994 if (!m_delayedFont
) return FALSE
;
2997 GdkWindow
*window
= (GdkWindow
*) NULL
;
2999 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
3001 window
= GetConnectWidget()->window
;
3005 // indicate that a new style has been set
3006 // but it couldn't get applied as the
3007 // widget hasn't been realized yet.
3008 m_delayedFont
= TRUE
;
3010 // pretend we have done something
3014 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
3015 if ( sysbg
== m_backgroundColour
)
3017 m_backgroundColour
= wxNullColour
;
3019 m_backgroundColour
= sysbg
;
3029 void wxWindow::CaptureMouse()
3031 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3033 wxCHECK_RET( g_captureWindow
== NULL
, wxT("CaptureMouse called twice") );
3035 GdkWindow
*window
= (GdkWindow
*) NULL
;
3037 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
3039 window
= GetConnectWidget()->window
;
3041 if (!window
) return;
3043 gdk_pointer_grab( window
, FALSE
,
3045 (GDK_BUTTON_PRESS_MASK
|
3046 GDK_BUTTON_RELEASE_MASK
|
3047 GDK_POINTER_MOTION_HINT_MASK
|
3048 GDK_POINTER_MOTION_MASK
),
3050 m_cursor
.GetCursor(),
3052 g_captureWindow
= this;
3055 void wxWindow::ReleaseMouse()
3057 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3059 wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") );
3061 GdkWindow
*window
= (GdkWindow
*) NULL
;
3063 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
3065 window
= GetConnectWidget()->window
;
3067 if (!window
) return;
3069 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3070 g_captureWindow
= (wxWindow
*) NULL
;
3073 bool wxWindow::IsRetained() const
3078 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3079 int range
, bool refresh
)
3081 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3083 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3085 m_hasScrolling
= TRUE
;
3087 if (orient
== wxHORIZONTAL
)
3089 float fpos
= (float)pos
;
3090 float frange
= (float)range
;
3091 float fthumb
= (float)thumbVisible
;
3092 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3093 if (fpos
< 0.0) fpos
= 0.0;
3095 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3096 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3098 SetScrollPos( orient
, pos
, refresh
);
3102 m_oldHorizontalPos
= fpos
;
3104 m_hAdjust
->lower
= 0.0;
3105 m_hAdjust
->upper
= frange
;
3106 m_hAdjust
->value
= fpos
;
3107 m_hAdjust
->step_increment
= 1.0;
3108 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3109 m_hAdjust
->page_size
= fthumb
;
3113 float fpos
= (float)pos
;
3114 float frange
= (float)range
;
3115 float fthumb
= (float)thumbVisible
;
3116 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3117 if (fpos
< 0.0) fpos
= 0.0;
3119 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3120 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3122 SetScrollPos( orient
, pos
, refresh
);
3126 m_oldVerticalPos
= fpos
;
3128 m_vAdjust
->lower
= 0.0;
3129 m_vAdjust
->upper
= frange
;
3130 m_vAdjust
->value
= fpos
;
3131 m_vAdjust
->step_increment
= 1.0;
3132 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3133 m_vAdjust
->page_size
= fthumb
;
3136 if (orient
== wxHORIZONTAL
)
3137 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3139 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3142 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3144 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3146 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3148 if (orient
== wxHORIZONTAL
)
3150 float fpos
= (float)pos
;
3151 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3152 if (fpos
< 0.0) fpos
= 0.0;
3153 m_oldHorizontalPos
= fpos
;
3155 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3156 m_hAdjust
->value
= fpos
;
3160 float fpos
= (float)pos
;
3161 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3162 if (fpos
< 0.0) fpos
= 0.0;
3163 m_oldVerticalPos
= fpos
;
3165 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3166 m_vAdjust
->value
= fpos
;
3173 if (m_wxwindow
->window
)
3175 if (orient
== wxHORIZONTAL
)
3176 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3178 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3185 int wxWindow::GetScrollThumb( int orient
) const
3187 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3189 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3191 if (orient
== wxHORIZONTAL
)
3192 return (int)(m_hAdjust
->page_size
+0.5);
3194 return (int)(m_vAdjust
->page_size
+0.5);
3197 int wxWindow::GetScrollPos( int orient
) const
3199 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3201 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3203 if (orient
== wxHORIZONTAL
)
3204 return (int)(m_hAdjust
->value
+0.5);
3206 return (int)(m_vAdjust
->value
+0.5);
3209 int wxWindow::GetScrollRange( int orient
) const
3211 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3213 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3215 if (orient
== wxHORIZONTAL
)
3216 return (int)(m_hAdjust
->upper
+0.5);
3218 return (int)(m_vAdjust
->upper
+0.5);
3221 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3223 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3225 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3227 gtk_myfixed_scroll( GTK_MYFIXED(m_wxwindow
), -dx
, -dy
);
3232 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3233 gdk_gc_set_exposures( m_scrollGC, TRUE );
3236 wxNode *node = m_children.First();
3239 wxWindow *child = (wxWindow*) node->Data();
3242 child->GetSize( &sx, &sy );
3243 child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
3244 node = node->Next();
3249 GetClientSize( &cw, &ch );
3250 int w = cw - abs(dx);
3251 int h = ch - abs(dy);
3253 if ((h < 0) || (w < 0))
3261 if (dx < 0) s_x = -dx;
3262 if (dy < 0) s_y = -dy;
3265 if (dx > 0) d_x = dx;
3266 if (dy > 0) d_y = dy;
3268 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
3269 m_wxwindow->window, s_x, s_y, w, h );
3272 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3273 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3274 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3275 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
3277 Refresh( TRUE, &rect );
3282 void wxWindow::SetScrolling(bool scroll
)
3284 m_isScrolling
= g_blockEventsOnScroll
= scroll
;