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
317 //-----------------------------------------------------------------------------
319 //-----------------------------------------------------------------------------
321 static void gtk_window_size_callback( GtkWidget
*WXUNUSED(widget
), GtkAllocation
* alloc
, wxWindow
*win
)
324 wxapp_install_idle_handler();
332 win
->m_sizeSet
= TRUE
;
335 wxPrintf( "OnSize from " );
336 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
337 wxPrintf( win->GetClassInfo()->GetClassName() );
338 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
341 (int)alloc->height );
344 wxSizeEvent
event( win
->GetSize(), win
->GetId() );
345 event
.SetEventObject( win
);
346 win
->GetEventHandler()->ProcessEvent( event
);
349 //-----------------------------------------------------------------------------
350 // key event conversion routines
351 //-----------------------------------------------------------------------------
353 #if (GTK_MINOR_VERSION == 0)
354 /* these functions are copied verbatim from GTK 1.2 */
356 gdkx_XConvertCase (KeySym symbol
,
360 register KeySym sym
= symbol
;
362 g_return_if_fail (lower
!= NULL
);
363 g_return_if_fail (upper
!= NULL
);
370 #if defined (GDK_A) && defined (GDK_Ooblique)
371 case 0: /* Latin 1 */
372 if ((sym
>= GDK_A
) && (sym
<= GDK_Z
))
373 *lower
+= (GDK_a
- GDK_A
);
374 else if ((sym
>= GDK_a
) && (sym
<= GDK_z
))
375 *upper
-= (GDK_a
- GDK_A
);
376 else if ((sym
>= GDK_Agrave
) && (sym
<= GDK_Odiaeresis
))
377 *lower
+= (GDK_agrave
- GDK_Agrave
);
378 else if ((sym
>= GDK_agrave
) && (sym
<= GDK_odiaeresis
))
379 *upper
-= (GDK_agrave
- GDK_Agrave
);
380 else if ((sym
>= GDK_Ooblique
) && (sym
<= GDK_Thorn
))
381 *lower
+= (GDK_oslash
- GDK_Ooblique
);
382 else if ((sym
>= GDK_oslash
) && (sym
<= GDK_thorn
))
383 *upper
-= (GDK_oslash
- GDK_Ooblique
);
387 #if defined (GDK_Aogonek) && defined (GDK_tcedilla)
388 case 1: /* Latin 2 */
389 /* Assume the KeySym is a legal value (ignore discontinuities) */
390 if (sym
== GDK_Aogonek
)
391 *lower
= GDK_aogonek
;
392 else if (sym
>= GDK_Lstroke
&& sym
<= GDK_Sacute
)
393 *lower
+= (GDK_lstroke
- GDK_Lstroke
);
394 else if (sym
>= GDK_Scaron
&& sym
<= GDK_Zacute
)
395 *lower
+= (GDK_scaron
- GDK_Scaron
);
396 else if (sym
>= GDK_Zcaron
&& sym
<= GDK_Zabovedot
)
397 *lower
+= (GDK_zcaron
- GDK_Zcaron
);
398 else if (sym
== GDK_aogonek
)
399 *upper
= GDK_Aogonek
;
400 else if (sym
>= GDK_lstroke
&& sym
<= GDK_sacute
)
401 *upper
-= (GDK_lstroke
- GDK_Lstroke
);
402 else if (sym
>= GDK_scaron
&& sym
<= GDK_zacute
)
403 *upper
-= (GDK_scaron
- GDK_Scaron
);
404 else if (sym
>= GDK_zcaron
&& sym
<= GDK_zabovedot
)
405 *upper
-= (GDK_zcaron
- GDK_Zcaron
);
406 else if (sym
>= GDK_Racute
&& sym
<= GDK_Tcedilla
)
407 *lower
+= (GDK_racute
- GDK_Racute
);
408 else if (sym
>= GDK_racute
&& sym
<= GDK_tcedilla
)
409 *upper
-= (GDK_racute
- GDK_Racute
);
413 #if defined (GDK_Hstroke) && defined (GDK_Cabovedot)
414 case 2: /* Latin 3 */
415 /* Assume the KeySym is a legal value (ignore discontinuities) */
416 if (sym
>= GDK_Hstroke
&& sym
<= GDK_Hcircumflex
)
417 *lower
+= (GDK_hstroke
- GDK_Hstroke
);
418 else if (sym
>= GDK_Gbreve
&& sym
<= GDK_Jcircumflex
)
419 *lower
+= (GDK_gbreve
- GDK_Gbreve
);
420 else if (sym
>= GDK_hstroke
&& sym
<= GDK_hcircumflex
)
421 *upper
-= (GDK_hstroke
- GDK_Hstroke
);
422 else if (sym
>= GDK_gbreve
&& sym
<= GDK_jcircumflex
)
423 *upper
-= (GDK_gbreve
- GDK_Gbreve
);
424 else if (sym
>= GDK_Cabovedot
&& sym
<= GDK_Scircumflex
)
425 *lower
+= (GDK_cabovedot
- GDK_Cabovedot
);
426 else if (sym
>= GDK_cabovedot
&& sym
<= GDK_scircumflex
)
427 *upper
-= (GDK_cabovedot
- GDK_Cabovedot
);
431 #if defined (GDK_Rcedilla) && defined (GDK_Amacron)
432 case 3: /* Latin 4 */
433 /* Assume the KeySym is a legal value (ignore discontinuities) */
434 if (sym
>= GDK_Rcedilla
&& sym
<= GDK_Tslash
)
435 *lower
+= (GDK_rcedilla
- GDK_Rcedilla
);
436 else if (sym
>= GDK_rcedilla
&& sym
<= GDK_tslash
)
437 *upper
-= (GDK_rcedilla
- GDK_Rcedilla
);
438 else if (sym
== GDK_ENG
)
440 else if (sym
== GDK_eng
)
442 else if (sym
>= GDK_Amacron
&& sym
<= GDK_Umacron
)
443 *lower
+= (GDK_amacron
- GDK_Amacron
);
444 else if (sym
>= GDK_amacron
&& sym
<= GDK_umacron
)
445 *upper
-= (GDK_amacron
- GDK_Amacron
);
449 #if defined (GDK_Serbian_DJE) && defined (GDK_Cyrillic_yu)
450 case 6: /* Cyrillic */
451 /* Assume the KeySym is a legal value (ignore discontinuities) */
452 if (sym
>= GDK_Serbian_DJE
&& sym
<= GDK_Serbian_DZE
)
453 *lower
-= (GDK_Serbian_DJE
- GDK_Serbian_dje
);
454 else if (sym
>= GDK_Serbian_dje
&& sym
<= GDK_Serbian_dze
)
455 *upper
+= (GDK_Serbian_DJE
- GDK_Serbian_dje
);
456 else if (sym
>= GDK_Cyrillic_YU
&& sym
<= GDK_Cyrillic_HARDSIGN
)
457 *lower
-= (GDK_Cyrillic_YU
- GDK_Cyrillic_yu
);
458 else if (sym
>= GDK_Cyrillic_yu
&& sym
<= GDK_Cyrillic_hardsign
)
459 *upper
+= (GDK_Cyrillic_YU
- GDK_Cyrillic_yu
);
461 #endif /* CYRILLIC */
463 #if defined (GDK_Greek_ALPHAaccent) && defined (GDK_Greek_finalsmallsigma)
465 /* Assume the KeySym is a legal value (ignore discontinuities) */
466 if (sym
>= GDK_Greek_ALPHAaccent
&& sym
<= GDK_Greek_OMEGAaccent
)
467 *lower
+= (GDK_Greek_alphaaccent
- GDK_Greek_ALPHAaccent
);
468 else if (sym
>= GDK_Greek_alphaaccent
&& sym
<= GDK_Greek_omegaaccent
&&
469 sym
!= GDK_Greek_iotaaccentdieresis
&&
470 sym
!= GDK_Greek_upsilonaccentdieresis
)
471 *upper
-= (GDK_Greek_alphaaccent
- GDK_Greek_ALPHAaccent
);
472 else if (sym
>= GDK_Greek_ALPHA
&& sym
<= GDK_Greek_OMEGA
)
473 *lower
+= (GDK_Greek_alpha
- GDK_Greek_ALPHA
);
474 else if (sym
>= GDK_Greek_alpha
&& sym
<= GDK_Greek_omega
&&
475 sym
!= GDK_Greek_finalsmallsigma
)
476 *upper
-= (GDK_Greek_alpha
- GDK_Greek_ALPHA
);
483 gdk_keyval_to_upper (guint keyval
)
487 KeySym lower_val
= 0;
488 KeySym upper_val
= 0;
490 gdkx_XConvertCase (keyval
, &lower_val
, &upper_val
);
497 static long map_to_unmodified_wx_keysym( KeySym keysym
)
504 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
506 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
512 case GDK_Super_R
: key_code
= WXK_ALT
; break;
513 case GDK_Menu
: key_code
= WXK_MENU
; break;
514 case GDK_Help
: key_code
= WXK_HELP
; break;
515 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
516 case GDK_ISO_Left_Tab
:
517 case GDK_Tab
: key_code
= WXK_TAB
; break;
518 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
519 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
520 case GDK_Return
: key_code
= WXK_RETURN
; break;
521 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
522 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
523 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
524 case GDK_Delete
: key_code
= WXK_DELETE
; break;
525 case GDK_Home
: key_code
= WXK_HOME
; break;
526 case GDK_Left
: key_code
= WXK_LEFT
; break;
527 case GDK_Up
: key_code
= WXK_UP
; break;
528 case GDK_Right
: key_code
= WXK_RIGHT
; break;
529 case GDK_Down
: key_code
= WXK_DOWN
; break;
530 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
531 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
532 case GDK_Next
: key_code
= WXK_NEXT
; break;
533 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
534 case GDK_End
: key_code
= WXK_END
; break;
535 case GDK_Begin
: key_code
= WXK_HOME
; break;
536 case GDK_Select
: key_code
= WXK_SELECT
; break;
537 case GDK_Print
: key_code
= WXK_PRINT
; break;
538 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
539 case GDK_Insert
: key_code
= WXK_INSERT
; break;
540 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
542 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
543 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
544 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
545 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
546 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
547 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
548 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
549 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
550 case GDK_KP_8
: key_code
= WXK_NUMPAD8
; break;
551 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
552 case GDK_KP_Space
: key_code
= WXK_NUMPAD_SPACE
; break;
553 case GDK_KP_Tab
: key_code
= WXK_NUMPAD_TAB
; break;
554 case GDK_KP_Enter
: key_code
= WXK_NUMPAD_ENTER
; break;
555 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
556 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
557 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
558 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
559 case GDK_KP_Home
: key_code
= WXK_NUMPAD_HOME
; break;
560 case GDK_KP_Left
: key_code
= WXK_NUMPAD_LEFT
; break;
561 case GDK_KP_Up
: key_code
= WXK_NUMPAD_UP
; break;
562 case GDK_KP_Right
: key_code
= WXK_NUMPAD_RIGHT
; break;
563 case GDK_KP_Down
: key_code
= WXK_NUMPAD_DOWN
; break;
564 case GDK_KP_Prior
: key_code
= WXK_NUMPAD_PRIOR
; break;
565 // case GDK_KP_Page_Up: key_code = WXK_NUMPAD_PAGEUP; break;
566 case GDK_KP_Next
: key_code
= WXK_NUMPAD_NEXT
; break;
567 // case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break;
568 case GDK_KP_End
: key_code
= WXK_NUMPAD_END
; break;
569 case GDK_KP_Begin
: key_code
= WXK_NUMPAD_BEGIN
; break;
570 case GDK_KP_Insert
: key_code
= WXK_NUMPAD_INSERT
; break;
571 case GDK_KP_Delete
: key_code
= WXK_NUMPAD_DELETE
; break;
572 case GDK_KP_Equal
: key_code
= WXK_NUMPAD_EQUAL
; break;
573 case GDK_KP_Multiply
: key_code
= WXK_NUMPAD_MULTIPLY
; break;
574 case GDK_KP_Add
: key_code
= WXK_NUMPAD_ADD
; break;
575 case GDK_KP_Separator
: key_code
= WXK_NUMPAD_SEPARATOR
; break;
576 case GDK_KP_Subtract
: key_code
= WXK_NUMPAD_SUBTRACT
; break;
577 case GDK_KP_Decimal
: key_code
= WXK_NUMPAD_DECIMAL
; break;
578 case GDK_KP_Divide
: key_code
= WXK_NUMPAD_DIVIDE
; break;
580 case GDK_F1
: key_code
= WXK_F1
; break;
581 case GDK_F2
: key_code
= WXK_F2
; break;
582 case GDK_F3
: key_code
= WXK_F3
; break;
583 case GDK_F4
: key_code
= WXK_F4
; break;
584 case GDK_F5
: key_code
= WXK_F5
; break;
585 case GDK_F6
: key_code
= WXK_F6
; break;
586 case GDK_F7
: key_code
= WXK_F7
; break;
587 case GDK_F8
: key_code
= WXK_F8
; break;
588 case GDK_F9
: key_code
= WXK_F9
; break;
589 case GDK_F10
: key_code
= WXK_F10
; break;
590 case GDK_F11
: key_code
= WXK_F11
; break;
591 case GDK_F12
: key_code
= WXK_F12
; break;
596 guint upper
= gdk_keyval_to_upper( keysym
);
597 keysym
= (upper
!= 0 ? upper
: keysym
); /* to be MSW compatible */
606 static long map_to_wx_keysym( KeySym keysym
)
612 case GDK_Menu
: key_code
= WXK_MENU
; break;
613 case GDK_Help
: key_code
= WXK_HELP
; break;
614 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
615 case GDK_ISO_Left_Tab
:
616 case GDK_Tab
: key_code
= WXK_TAB
; break;
617 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
618 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
619 case GDK_Return
: key_code
= WXK_RETURN
; break;
620 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
621 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
622 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
623 case GDK_Delete
: key_code
= WXK_DELETE
; break;
624 case GDK_Home
: key_code
= WXK_HOME
; break;
625 case GDK_Left
: key_code
= WXK_LEFT
; break;
626 case GDK_Up
: key_code
= WXK_UP
; break;
627 case GDK_Right
: key_code
= WXK_RIGHT
; break;
628 case GDK_Down
: key_code
= WXK_DOWN
; break;
629 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
630 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
631 case GDK_Next
: key_code
= WXK_NEXT
; break;
632 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
633 case GDK_End
: key_code
= WXK_END
; break;
634 case GDK_Begin
: key_code
= WXK_HOME
; break;
635 case GDK_Select
: key_code
= WXK_SELECT
; break;
636 case GDK_Print
: key_code
= WXK_PRINT
; break;
637 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
638 case GDK_Insert
: key_code
= WXK_INSERT
; break;
639 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
641 case GDK_KP_0
: key_code
= '0'; break;
642 case GDK_KP_1
: key_code
= '1'; break;
643 case GDK_KP_2
: key_code
= '2'; break;
644 case GDK_KP_3
: key_code
= '3'; break;
645 case GDK_KP_4
: key_code
= '4'; break;
646 case GDK_KP_5
: key_code
= '5'; break;
647 case GDK_KP_6
: key_code
= '6'; break;
648 case GDK_KP_7
: key_code
= '7'; break;
649 case GDK_KP_8
: key_code
= '8'; break;
650 case GDK_KP_9
: key_code
= '9'; break;
651 case GDK_KP_Space
: key_code
= ' '; break;
652 case GDK_KP_Tab
: key_code
= WXK_TAB
; break; /* or '\t' ??? */
653 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break; /* or '\r' ??? */
654 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
655 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
656 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
657 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
658 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
659 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
660 case GDK_KP_Up
: key_code
= WXK_UP
; break;
661 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
662 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
663 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
664 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
665 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
666 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
667 case GDK_KP_End
: key_code
= WXK_END
; break;
668 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
669 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
670 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
671 case GDK_KP_Equal
: key_code
= '='; break;
672 case GDK_KP_Multiply
: key_code
= '*'; break;
673 case GDK_KP_Add
: key_code
= '+'; break;
674 case GDK_KP_Separator
: key_code
= ','; break;
675 case GDK_KP_Subtract
: key_code
= '-'; break;
676 case GDK_KP_Decimal
: key_code
= '.'; break;
677 case GDK_KP_Divide
: key_code
= '/'; break;
679 case GDK_F1
: key_code
= WXK_F1
; break;
680 case GDK_F2
: key_code
= WXK_F2
; break;
681 case GDK_F3
: key_code
= WXK_F3
; break;
682 case GDK_F4
: key_code
= WXK_F4
; break;
683 case GDK_F5
: key_code
= WXK_F5
; break;
684 case GDK_F6
: key_code
= WXK_F6
; break;
685 case GDK_F7
: key_code
= WXK_F7
; break;
686 case GDK_F8
: key_code
= WXK_F8
; break;
687 case GDK_F9
: key_code
= WXK_F9
; break;
688 case GDK_F10
: key_code
= WXK_F10
; break;
689 case GDK_F11
: key_code
= WXK_F11
; break;
690 case GDK_F12
: key_code
= WXK_F12
; break;
703 //-----------------------------------------------------------------------------
704 // "expose_event" of m_wxwindow
705 //-----------------------------------------------------------------------------
707 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
712 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
714 gdk_event
->area
.width
,
715 gdk_event
->area
.height
);
717 if (gdk_event
->count
> 0)
721 wxPrintf( "OnExpose from " );
722 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
723 wxPrintf( win->GetClassInfo()->GetClassName() );
724 wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x,
725 (int)gdk_event->area.y,
726 (int)gdk_event->area.width,
727 (int)gdk_event->area.height );
730 wxEraseEvent
eevent( win
->GetId() );
731 eevent
.SetEventObject( win
);
732 win
->GetEventHandler()->ProcessEvent(eevent
);
734 wxPaintEvent
event( win
->GetId() );
735 event
.SetEventObject( win
);
736 win
->GetEventHandler()->ProcessEvent( event
);
738 win
->GetUpdateRegion().Clear();
741 //-----------------------------------------------------------------------------
742 // "draw" of m_wxwindow
743 //-----------------------------------------------------------------------------
745 static void gtk_window_draw_callback( GtkWidget
*widget
, GdkRectangle
*rect
, wxWindow
*win
)
748 wxapp_install_idle_handler();
753 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
754 rect
->width
, rect
->height
);
757 wxPrintf( "OnDraw from " );
758 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
759 printf( win->GetClassInfo()->GetClassName() );
760 wxPrintf( " %d %d %d %d\n", (int)rect->x,
766 wxEraseEvent
eevent( win
->GetId() );
767 eevent
.SetEventObject( win
);
768 win
->GetEventHandler()->ProcessEvent(eevent
);
770 wxPaintEvent
event( win
->GetId() );
771 event
.SetEventObject( win
);
772 win
->GetEventHandler()->ProcessEvent( event
);
774 win
->GetUpdateRegion().Clear();
777 //-----------------------------------------------------------------------------
778 // "key_press_event" from any window
779 //-----------------------------------------------------------------------------
781 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
784 wxapp_install_idle_handler();
786 if (!win
->m_hasVMT
) return FALSE
;
787 if (g_blockEventsOnDrag
) return FALSE
;
790 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
791 if (gdk_event->state & GDK_SHIFT_MASK)
792 printf( "ShiftDown.\n" );
794 printf( "ShiftUp.\n" );
795 if (gdk_event->state & GDK_CONTROL_MASK)
796 printf( "ControlDown.\n" );
798 printf( "ControlUp.\n" );
803 GdkModifierType state
;
804 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
806 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
808 /* sending unknown key events doesn't really make sense */
809 if (key_code
== 0) return FALSE
;
813 wxKeyEvent
event( wxEVT_KEY_DOWN
);
814 event
.SetTimestamp( gdk_event
->time
);
815 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
816 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
817 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
818 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
819 event
.m_keyCode
= key_code
;
820 event
.m_scanCode
= gdk_event
->keyval
;
823 event
.SetEventObject( win
);
824 ret
= win
->GetEventHandler()->ProcessEvent( event
);
826 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
831 wxWindow
*ancestor
= win
;
834 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
837 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
838 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
841 ancestor
= ancestor
->GetParent();
844 #endif // wxUSE_ACCEL
845 /* wxMSW doesn't send char events with Alt pressed */
846 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
847 will only be sent if it is not a menu accelerator. */
848 if ((key_code
!= 0) && ! ret
)
850 wxKeyEvent
event2( wxEVT_CHAR
);
851 event2
.SetTimestamp( gdk_event
->time
);
852 event2
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
853 event2
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
854 event2
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
855 event2
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
856 event2
.m_keyCode
= key_code
;
857 event2
.m_scanCode
= gdk_event
->keyval
;
860 event2
.SetEventObject( win
);
861 ret
= (ret
|| win
->GetEventHandler()->ProcessEvent( event2
));
864 /* win is a control: tab can be propagated up */
866 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
867 (win
->HasFlag(wxTE_PROCESS_TAB
) == 0))
869 wxNavigationKeyEvent new_event
;
870 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
871 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
872 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
873 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
874 new_event
.SetCurrentFocus( win
);
875 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
878 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
880 (gdk_event
->keyval
== GDK_Escape
) )
882 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
883 new_event
.SetEventObject( win
);
884 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
887 #if (GTK_MINOR_VERSION > 0)
888 /* pressing F10 will activate the menu bar of the top frame */
890 (gdk_event
->keyval
== GDK_F10
) )
892 wxWindow
*ancestor
= win
;
895 if (wxIsKindOf(ancestor
,wxFrame
))
897 wxFrame
*frame
= (wxFrame
*) ancestor
;
898 wxMenuBar
*menubar
= frame
->GetMenuBar();
901 wxNode
*node
= menubar
->GetMenus().First();
904 // doesn't work correctly
905 // wxMenu *firstMenu = (wxMenu*) node->Data();
906 // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
912 ancestor
= ancestor
->GetParent();
918 Damn, I forgot why this didn't work, but it didn't work.
920 // win is a panel: up can be propagated to the panel
921 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
922 (gdk_event->keyval == GDK_Up))
924 win->m_parent->SetFocus();
928 // win is a panel: left/right can be propagated to the panel
929 if ((!ret) && (win->m_wxwindow) &&
930 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
931 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
933 wxNavigationKeyEvent new_event;
934 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
935 new_event.SetCurrentFocus( win );
936 ret = win->GetEventHandler()->ProcessEvent( new_event );
942 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
949 //-----------------------------------------------------------------------------
950 // "key_release_event" from any window
951 //-----------------------------------------------------------------------------
953 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
956 wxapp_install_idle_handler();
958 if (!win
->m_hasVMT
) return FALSE
;
959 if (g_blockEventsOnDrag
) return FALSE
;
962 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
963 if (gdk_event->state & GDK_SHIFT_MASK)
964 printf( "ShiftDown.\n" );
966 printf( "ShiftUp.\n" );
967 if (gdk_event->state & GDK_CONTROL_MASK)
968 printf( "ControlDown.\n" );
970 printf( "ControlUp.\n" );
974 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
976 /* sending unknown key events doesn't really make sense */
977 if (key_code
== 0) return FALSE
;
981 GdkModifierType state
;
982 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
984 wxKeyEvent
event( wxEVT_KEY_UP
);
985 event
.SetTimestamp( gdk_event
->time
);
986 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
987 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
988 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
989 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
990 event
.m_keyCode
= key_code
;
991 event
.m_scanCode
= gdk_event
->keyval
;
994 event
.SetEventObject( win
);
996 if (win
->GetEventHandler()->ProcessEvent( event
))
998 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
1005 //-----------------------------------------------------------------------------
1006 // "button_press_event"
1007 //-----------------------------------------------------------------------------
1009 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1012 wxapp_install_idle_handler();
1015 wxPrintf( wxT("1) OnButtonPress from ") );
1016 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1017 wxPrintf( win->GetClassInfo()->GetClassName() );
1018 wxPrintf( wxT(".\n") );
1020 if (!win
->m_hasVMT
) return FALSE
;
1021 if (g_blockEventsOnDrag
) return TRUE
;
1022 if (g_blockEventsOnScroll
) return TRUE
;
1024 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1026 if (win
->m_wxwindow
)
1028 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
1030 gtk_widget_grab_focus (win
->m_wxwindow
);
1033 wxPrintf( wxT("GrabFocus from ") );
1034 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1035 wxPrintf( win->GetClassInfo()->GetClassName() );
1036 wxPrintf( wxT(".\n") );
1043 wxPrintf( wxT("2) OnButtonPress from ") );
1044 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1045 wxPrintf( win->GetClassInfo()->GetClassName() );
1046 wxPrintf( wxT(".\n") );
1049 wxEventType event_type
= wxEVT_LEFT_DOWN
;
1051 if (gdk_event
->button
== 1)
1053 switch (gdk_event
->type
)
1055 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
1056 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
1060 else if (gdk_event
->button
== 2)
1062 switch (gdk_event
->type
)
1064 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
1065 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
1069 else if (gdk_event
->button
== 3)
1071 switch (gdk_event
->type
)
1073 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
1074 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
1079 wxMouseEvent
event( event_type
);
1080 event
.SetTimestamp( gdk_event
->time
);
1081 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1082 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1083 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1084 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1085 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1086 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1087 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1089 event
.m_x
= (long)gdk_event
->x
;
1090 event
.m_y
= (long)gdk_event
->y
;
1092 // Some control don't have their own X window and thus cannot get
1095 if (!g_captureWindow
)
1097 wxNode
*node
= win
->GetChildren().First();
1100 wxWindow
*child
= (wxWindow
*)node
->Data();
1102 if (child
->m_isStaticBox
)
1104 // wxStaticBox is transparent in the box itself
1107 int xx1
= child
->m_x
;
1108 int yy1
= child
->m_y
;
1109 int xx2
= child
->m_x
+ child
->m_width
;
1110 int yy2
= child
->m_x
+ child
->m_height
;
1113 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1115 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1117 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1119 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1122 event
.m_x
-= child
->m_x
;
1123 event
.m_y
-= child
->m_y
;
1130 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1131 (child
->m_x
<= event
.m_x
) &&
1132 (child
->m_y
<= event
.m_y
) &&
1133 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1134 (child
->m_y
+child
->m_height
>= event
.m_y
))
1137 event
.m_x
-= child
->m_x
;
1138 event
.m_y
-= child
->m_y
;
1142 node
= node
->Next();
1146 event
.SetEventObject( win
);
1148 gs_timeLastClick
= gdk_event
->time
;
1150 if (win
->GetEventHandler()->ProcessEvent( event
))
1152 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
1159 //-----------------------------------------------------------------------------
1160 // "button_release_event"
1161 //-----------------------------------------------------------------------------
1163 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1166 wxapp_install_idle_handler();
1168 if (!win
->m_hasVMT
) return FALSE
;
1169 if (g_blockEventsOnDrag
) return FALSE
;
1170 if (g_blockEventsOnScroll
) return FALSE
;
1172 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1175 printf( "OnButtonRelease from " );
1176 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1177 printf( win->GetClassInfo()->GetClassName() );
1181 wxEventType event_type
= wxEVT_NULL
;
1183 switch (gdk_event
->button
)
1185 case 1: event_type
= wxEVT_LEFT_UP
; break;
1186 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
1187 case 3: event_type
= wxEVT_RIGHT_UP
; break;
1190 wxMouseEvent
event( event_type
);
1191 event
.SetTimestamp( gdk_event
->time
);
1192 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1193 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1194 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1195 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1196 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1197 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1198 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1199 event
.m_x
= (long)gdk_event
->x
;
1200 event
.m_y
= (long)gdk_event
->y
;
1202 // Some control don't have their own X window and thus cannot get
1205 if (!g_captureWindow
)
1207 wxNode
*node
= win
->GetChildren().First();
1210 wxWindow
*child
= (wxWindow
*)node
->Data();
1212 if (child
->m_isStaticBox
)
1214 // wxStaticBox is transparent in the box itself
1217 int xx1
= child
->m_x
;
1218 int yy1
= child
->m_y
;
1219 int xx2
= child
->m_x
+ child
->m_width
;
1220 int yy2
= child
->m_x
+ child
->m_height
;
1223 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1225 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1227 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1229 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1232 event
.m_x
-= child
->m_x
;
1233 event
.m_y
-= child
->m_y
;
1240 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1241 (child
->m_x
<= event
.m_x
) &&
1242 (child
->m_y
<= event
.m_y
) &&
1243 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1244 (child
->m_y
+child
->m_height
>= event
.m_y
))
1247 event
.m_x
-= child
->m_x
;
1248 event
.m_y
-= child
->m_y
;
1252 node
= node
->Next();
1256 event
.SetEventObject( win
);
1258 if (win
->GetEventHandler()->ProcessEvent( event
))
1260 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1267 //-----------------------------------------------------------------------------
1268 // "motion_notify_event"
1269 //-----------------------------------------------------------------------------
1271 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1274 wxapp_install_idle_handler();
1276 if (!win
->m_hasVMT
) return FALSE
;
1277 if (g_blockEventsOnDrag
) return FALSE
;
1278 if (g_blockEventsOnScroll
) return FALSE
;
1280 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1282 if (gdk_event
->is_hint
)
1286 GdkModifierType state
;
1287 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1293 printf( "OnMotion from " );
1294 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1295 printf( win->GetClassInfo()->GetClassName() );
1299 wxMouseEvent
event( wxEVT_MOTION
);
1300 event
.SetTimestamp( gdk_event
->time
);
1301 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1302 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1303 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1304 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1305 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1306 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1307 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1309 event
.m_x
= (long)gdk_event
->x
;
1310 event
.m_y
= (long)gdk_event
->y
;
1312 // Some control don't have their own X window and thus cannot get
1315 if (!g_captureWindow
)
1317 wxNode
*node
= win
->GetChildren().First();
1320 wxWindow
*child
= (wxWindow
*)node
->Data();
1322 if (child
->m_isStaticBox
)
1324 // wxStaticBox is transparent in the box itself
1327 int xx1
= child
->m_x
;
1328 int yy1
= child
->m_y
;
1329 int xx2
= child
->m_x
+ child
->m_width
;
1330 int yy2
= child
->m_x
+ child
->m_height
;
1333 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1335 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1337 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1339 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1342 event
.m_x
-= child
->m_x
;
1343 event
.m_y
-= child
->m_y
;
1350 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1351 (child
->m_x
<= event
.m_x
) &&
1352 (child
->m_y
<= event
.m_y
) &&
1353 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
1354 (child
->m_y
+child
->m_height
>= event
.m_y
))
1357 event
.m_x
-= child
->m_x
;
1358 event
.m_y
-= child
->m_y
;
1362 node
= node
->Next();
1366 event
.SetEventObject( win
);
1368 if (win
->GetEventHandler()->ProcessEvent( event
))
1370 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1377 //-----------------------------------------------------------------------------
1379 //-----------------------------------------------------------------------------
1381 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1384 wxapp_install_idle_handler();
1386 if (!win
->m_hasVMT
) return FALSE
;
1387 if (g_blockEventsOnDrag
) return FALSE
;
1389 g_focusWindow
= win
;
1391 if (win
->m_wxwindow
)
1393 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1395 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1397 printf( "SetFocus flag from " );
1398 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1399 printf( win->GetClassInfo()->GetClassName() );
1407 printf( "OnSetFocus from " );
1408 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1409 printf( win->GetClassInfo()->GetClassName() );
1411 printf( WXSTRINGCAST win->GetLabel() );
1415 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1416 event
.SetEventObject( win
);
1418 if (win
->GetEventHandler()->ProcessEvent( event
))
1420 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1427 //-----------------------------------------------------------------------------
1428 // "focus_out_event"
1429 //-----------------------------------------------------------------------------
1431 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1434 wxapp_install_idle_handler();
1436 if (!win
->m_hasVMT
) return FALSE
;
1437 if (g_blockEventsOnDrag
) return FALSE
;
1439 if (win
->m_wxwindow
)
1441 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1442 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1446 printf( "OnKillFocus from " );
1447 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1448 printf( win->GetClassInfo()->GetClassName() );
1452 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1453 event
.SetEventObject( win
);
1455 if (win
->GetEventHandler()->ProcessEvent( event
))
1457 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1464 //-----------------------------------------------------------------------------
1465 // "enter_notify_event"
1466 //-----------------------------------------------------------------------------
1468 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1471 wxapp_install_idle_handler();
1473 if (!win
->m_hasVMT
) return FALSE
;
1474 if (g_blockEventsOnDrag
) return FALSE
;
1476 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1478 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1479 #if (GTK_MINOR_VERSION > 0)
1480 event
.SetTimestamp( gdk_event
->time
);
1482 event
.SetEventObject( win
);
1486 GdkModifierType state
= (GdkModifierType
)0;
1488 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1490 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1491 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1492 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1493 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1494 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1495 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1496 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1498 event
.m_x
= (long)x
;
1499 event
.m_y
= (long)y
;
1501 if (win
->GetEventHandler()->ProcessEvent( event
))
1503 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1510 //-----------------------------------------------------------------------------
1511 // "leave_notify_event"
1512 //-----------------------------------------------------------------------------
1514 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1517 wxapp_install_idle_handler();
1519 if (!win
->m_hasVMT
) return FALSE
;
1520 if (g_blockEventsOnDrag
) return FALSE
;
1522 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1524 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1525 #if (GTK_MINOR_VERSION > 0)
1526 event
.SetTimestamp( gdk_event
->time
);
1528 event
.SetEventObject( win
);
1532 GdkModifierType state
= (GdkModifierType
)0;
1534 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1536 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1537 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1538 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1539 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1540 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1541 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1542 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1544 event
.m_x
= (long)x
;
1545 event
.m_y
= (long)y
;
1547 if (win
->GetEventHandler()->ProcessEvent( event
))
1549 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1556 //-----------------------------------------------------------------------------
1557 // "value_changed" from m_vAdjust
1558 //-----------------------------------------------------------------------------
1560 static void gtk_window_vscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1563 wxapp_install_idle_handler();
1565 if (g_blockEventsOnDrag
) return;
1567 if (!win
->m_hasVMT
) return;
1569 float diff
= adjust
->value
- win
->m_oldVerticalPos
;
1570 if (fabs(diff
) < 0.2) return;
1572 win
->m_oldVerticalPos
= adjust
->value
;
1574 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1575 GtkRange
*range
= GTK_RANGE( scrolledWindow
->vscrollbar
);
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
, wxVERTICAL
);
1586 event
.SetEventObject( win
);
1587 win
->GetEventHandler()->ProcessEvent( event
);
1590 //-----------------------------------------------------------------------------
1591 // "value_changed" from m_hAdjust
1592 //-----------------------------------------------------------------------------
1594 static void gtk_window_hscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1597 wxapp_install_idle_handler();
1599 if (g_blockEventsOnDrag
) return;
1600 if (!win
->m_hasVMT
) return;
1602 float diff
= adjust
->value
- win
->m_oldHorizontalPos
;
1603 if (fabs(diff
) < 0.2) return;
1605 win
->m_oldHorizontalPos
= adjust
->value
;
1607 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1608 GtkRange
*range
= GTK_RANGE( scrolledWindow
->hscrollbar
);
1610 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1611 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1612 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1613 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1614 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1616 int value
= (int)(adjust
->value
+0.5);
1618 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1619 event
.SetEventObject( win
);
1620 win
->GetEventHandler()->ProcessEvent( event
);
1623 //-----------------------------------------------------------------------------
1624 // "changed" from m_vAdjust
1625 //-----------------------------------------------------------------------------
1627 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1630 wxapp_install_idle_handler();
1632 if (g_blockEventsOnDrag
) return;
1633 if (!win
->m_hasVMT
) return;
1635 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1636 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1638 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1639 event
.SetEventObject( win
);
1640 win
->GetEventHandler()->ProcessEvent( event
);
1643 //-----------------------------------------------------------------------------
1644 // "changed" from m_hAdjust
1645 //-----------------------------------------------------------------------------
1647 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1650 wxapp_install_idle_handler();
1652 if (g_blockEventsOnDrag
) return;
1653 if (!win
->m_hasVMT
) return;
1655 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1656 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1658 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1659 event
.SetEventObject( win
);
1660 win
->GetEventHandler()->ProcessEvent( event
);
1663 //-----------------------------------------------------------------------------
1664 // "button_press_event" from scrollbar
1665 //-----------------------------------------------------------------------------
1667 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1668 GdkEventButton
*WXUNUSED(gdk_event
),
1672 wxapp_install_idle_handler();
1674 // don't test here as we can release the mouse while being over
1675 // a different window than the slider
1677 // if (gdk_event->window != widget->slider) return FALSE;
1679 win
->SetScrolling( TRUE
);
1684 //-----------------------------------------------------------------------------
1685 // "button_release_event" from scrollbar
1686 //-----------------------------------------------------------------------------
1688 static gint
gtk_scrollbar_button_release_callback( GtkRange
*WXUNUSED(widget
),
1689 GdkEventButton
*WXUNUSED(gdk_event
),
1693 // don't test here as we can release the mouse while being over
1694 // a different window than the slider
1696 // if (gdk_event->window != widget->slider) return FALSE;
1698 win
->SetScrolling( FALSE
);
1703 // ----------------------------------------------------------------------------
1704 // this wxWindowBase function is implemented here (in platform-specific file)
1705 // because it is static and so couldn't be made virtual
1706 // ----------------------------------------------------------------------------
1708 wxWindow
*wxWindowBase::FindFocus()
1710 return g_focusWindow
;
1713 //-----------------------------------------------------------------------------
1714 // "realize" from m_widget
1715 //-----------------------------------------------------------------------------
1717 /* we cannot set colours and fonts before the widget has
1718 been realized, so we do this directly after realization */
1721 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1724 wxapp_install_idle_handler();
1726 if (win
->m_delayedFont
)
1727 win
->SetFont( win
->GetFont() );
1729 if (win
->m_delayedBackgroundColour
)
1730 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1732 if (win
->m_delayedForegroundColour
)
1733 win
->SetForegroundColour( win
->GetForegroundColour() );
1735 wxWindowCreateEvent
event( win
);
1736 event
.SetEventObject( win
);
1737 win
->GetEventHandler()->ProcessEvent( event
);
1742 //-----------------------------------------------------------------------------
1743 // InsertChild for wxWindow.
1744 //-----------------------------------------------------------------------------
1746 /* Callback for wxWindow. This very strange beast has to be used because
1747 * C++ has no virtual methods in a constructor. We have to emulate a
1748 * virtual function here as wxNotebook requires a different way to insert
1749 * a child in it. I had opted for creating a wxNotebookPage window class
1750 * which would have made this superfluous (such in the MDI window system),
1751 * but no-one was listening to me... */
1753 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1755 /* the window might have been scrolled already, do we
1756 have to adapt the position */
1757 GtkMyFixed
*myfixed
= GTK_MYFIXED(parent
->m_wxwindow
);
1758 child
->m_x
+= myfixed
->xoffset
;
1759 child
->m_y
+= myfixed
->yoffset
;
1761 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1762 GTK_WIDGET(child
->m_widget
),
1768 if (parent
->HasFlag(wxTAB_TRAVERSAL
))
1770 /* we now allow a window to get the focus as long as it
1771 doesn't have any children. */
1772 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1776 //-----------------------------------------------------------------------------
1778 //-----------------------------------------------------------------------------
1780 wxWindow
* wxGetActiveWindow()
1782 return g_focusWindow
;
1785 //-----------------------------------------------------------------------------
1787 //-----------------------------------------------------------------------------
1789 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1791 void wxWindow::Init()
1797 m_widget
= (GtkWidget
*) NULL
;
1798 m_wxwindow
= (GtkWidget
*) NULL
;
1808 m_needParent
= TRUE
;
1809 m_isBeingDeleted
= FALSE
;
1813 m_hasScrolling
= FALSE
;
1814 m_isScrolling
= FALSE
;
1816 m_hAdjust
= (GtkAdjustment
*) NULL
;
1817 m_vAdjust
= (GtkAdjustment
*) NULL
;
1818 m_oldHorizontalPos
= 0.0;
1819 m_oldVerticalPos
= 0.0;
1822 m_widgetStyle
= (GtkStyle
*) NULL
;
1824 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1826 m_isStaticBox
= FALSE
;
1827 m_isRadioButton
= FALSE
;
1829 m_acceptsFocus
= FALSE
;
1831 m_cursor
= *wxSTANDARD_CURSOR
;
1834 wxWindow::wxWindow()
1839 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1840 const wxPoint
&pos
, const wxSize
&size
,
1841 long style
, const wxString
&name
)
1845 Create( parent
, id
, pos
, size
, style
, name
);
1848 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1849 const wxPoint
&pos
, const wxSize
&size
,
1850 long style
, const wxString
&name
)
1852 if (!PreCreation( parent
, pos
, size
) ||
1853 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
1855 wxFAIL_MSG( wxT("wxWindow creation failed") );
1859 m_insertCallback
= wxInsertChildInWindow
;
1861 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1862 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1865 debug_focus_in( m_widget
, wxT("wxWindow::m_widget"), name
);
1868 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1871 debug_focus_in( scrolledWindow
->hscrollbar
, wxT("wxWindow::hsrcollbar"), name
);
1872 debug_focus_in( scrolledWindow
->vscrollbar
, wxT("wxWindow::vsrcollbar"), name
);
1875 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1876 scroll_class
->scrollbar_spacing
= 0;
1878 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1880 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1881 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1883 m_wxwindow
= gtk_myfixed_new();
1886 debug_focus_in( m_wxwindow
, wxT("wxWindow::m_wxwindow"), name
);
1889 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1891 #if (GTK_MINOR_VERSION > 0)
1892 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1894 if (HasFlag(wxRAISED_BORDER
))
1896 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_OUT
);
1898 else if (HasFlag(wxSUNKEN_BORDER
))
1900 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_IN
);
1902 else if (HasFlag(wxSIMPLE_BORDER
))
1904 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_THIN
);
1908 gtk_myfixed_set_shadow_type( myfixed
, GTK_MYSHADOW_NONE
);
1910 #else // GTK_MINOR_VERSION == 0
1911 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1913 if (HasFlag(wxRAISED_BORDER
))
1915 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1917 else if (HasFlag(wxSUNKEN_BORDER
))
1919 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1923 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1925 #endif // GTK_MINOR_VERSION
1927 if (HasFlag(wxTAB_TRAVERSAL
))
1929 /* we now allow a window to get the focus as long as it
1930 doesn't have any children. */
1931 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1932 m_acceptsFocus
= FALSE
;
1936 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1937 m_acceptsFocus
= TRUE
;
1940 #if (GTK_MINOR_VERSION == 0)
1941 // shut the viewport up
1942 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1943 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1944 #endif // GTK_MINOR_VERSION == 0
1946 // I _really_ don't want scrollbars in the beginning
1947 m_vAdjust
->lower
= 0.0;
1948 m_vAdjust
->upper
= 1.0;
1949 m_vAdjust
->value
= 0.0;
1950 m_vAdjust
->step_increment
= 1.0;
1951 m_vAdjust
->page_increment
= 1.0;
1952 m_vAdjust
->page_size
= 5.0;
1953 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1954 m_hAdjust
->lower
= 0.0;
1955 m_hAdjust
->upper
= 1.0;
1956 m_hAdjust
->value
= 0.0;
1957 m_hAdjust
->step_increment
= 1.0;
1958 m_hAdjust
->page_increment
= 1.0;
1959 m_hAdjust
->page_size
= 5.0;
1960 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1962 // these handlers block mouse events to any window during scrolling such as
1963 // motion events and prevent GTK and wxWindows from fighting over where the
1966 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1967 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1969 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1970 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1972 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1973 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1975 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1976 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1978 // these handlers get notified when screen updates are required either when
1979 // scrolling or when the window size (and therefore scrollbar configuration)
1982 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1983 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1984 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1985 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1987 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1988 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1989 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1990 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1992 gtk_widget_show( m_wxwindow
);
1995 m_parent
->DoAddChild( this );
2004 wxWindow::~wxWindow()
2006 m_isBeingDeleted
= TRUE
;
2015 m_parent
->RemoveChild( this );
2019 gtk_style_unref( m_widgetStyle
);
2020 m_widgetStyle
= (GtkStyle
*) NULL
;
2025 gtk_widget_destroy( m_wxwindow
);
2026 m_wxwindow
= (GtkWidget
*) NULL
;
2031 gtk_widget_destroy( m_widget
);
2032 m_widget
= (GtkWidget
*) NULL
;
2036 bool wxWindow::PreCreation( wxWindow
*parent
, const wxPoint
&pos
, const wxSize
&size
)
2038 wxCHECK_MSG( !m_needParent
|| parent
, FALSE
, wxT("Need complete parent.") );
2040 /* this turns -1 into 20 so that a minimal window is
2041 visible even although -1,-1 has been given as the
2042 size of the window. the same trick is used in other
2043 ports and should make debugging easier */
2044 m_width
= WidthDefault(size
.x
);
2045 m_height
= HeightDefault(size
.y
);
2050 /* some reasonable defaults */
2055 m_x
= (gdk_screen_width () - m_width
) / 2;
2056 if (m_x
< 10) m_x
= 10;
2060 m_y
= (gdk_screen_height () - m_height
) / 2;
2061 if (m_y
< 10) m_y
= 10;
2068 void wxWindow::PostCreation()
2070 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2074 /* frames have their own callback */
2075 gtk_signal_connect( GTK_OBJECT(m_widget
), "size_allocate",
2076 GTK_SIGNAL_FUNC(gtk_window_size_callback
), (gpointer
)this );
2083 /* these get reported to wxWindows -> wxPaintEvent */
2084 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
2085 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
2087 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
2088 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
2091 #if (GTK_MINOR_VERSION > 0)
2092 /* these are called when the "sunken" or "raised" borders are drawn */
2093 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
2094 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
2096 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
2097 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
2101 GtkWidget
*connect_widget
= GetConnectWidget();
2103 ConnectWidget( connect_widget
);
2105 /* we cannot set colours, fonts and cursors before the widget has
2106 been realized, so we do this directly after realization */
2107 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
2108 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
2113 void wxWindow::ConnectWidget( GtkWidget
*widget
)
2115 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
2116 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
2118 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
2119 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
2121 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
2122 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
2124 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
2125 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
2127 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
2128 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
2130 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
2131 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2133 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
2134 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2136 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
2137 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
2139 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
2140 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
2143 bool wxWindow::Destroy()
2145 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2149 return wxWindowBase::Destroy();
2152 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
2154 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2155 wxASSERT_MSG( (m_parent
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") );
2157 if (m_resizing
) return; /* I don't like recursions */
2160 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
2162 /* don't set the size for children of wxNotebook, just take the values. */
2172 int old_width
= m_width
;
2173 int old_height
= m_height
;
2175 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_parent
->m_wxwindow
);
2177 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
2179 if (x
!= -1) m_x
= x
+ myfixed
->xoffset
;
2180 if (y
!= -1) m_y
= y
+ myfixed
->yoffset
;
2181 if (width
!= -1) m_width
= width
;
2182 if (height
!= -1) m_height
= height
;
2186 m_x
= x
+ myfixed
->xoffset
;
2187 m_y
= y
+ myfixed
->yoffset
;
2192 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2194 if (width
== -1) m_width
= 80;
2197 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2199 if (height
== -1) m_height
= 26;
2202 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2203 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2204 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2205 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2208 int bottom_border
= 0;
2210 if (GTK_WIDGET_CAN_DEFAULT(m_widget
))
2212 /* the default button has a border around it */
2217 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
2222 m_height
+border
+bottom_border
);
2224 if ((old_width
!= m_width
) ||
2225 (old_height
!= m_height
))
2232 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
2233 event.SetEventObject( this );
2234 GetEventHandler()->ProcessEvent( event );
2239 void wxWindow::OnInternalIdle()
2241 wxCursor cursor
= m_cursor
;
2242 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2246 /* I now set the cursor the anew in every OnInternalIdle call
2247 as setting the cursor in a parent window also effects the
2248 windows above so that checking for the current cursor is
2253 GdkWindow
*window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2255 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2257 if (!g_globalCursor
.Ok())
2258 cursor
= *wxSTANDARD_CURSOR
;
2260 window
= m_widget
->window
;
2261 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2262 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2268 GdkWindow
*window
= m_widget
->window
;
2269 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2270 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2278 void wxWindow::DoGetSize( int *width
, int *height
) const
2280 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2282 if (width
) (*width
) = m_width
;
2283 if (height
) (*height
) = m_height
;
2286 void wxWindow::DoSetClientSize( int width
, int height
)
2288 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2292 SetSize( width
, height
);
2299 #if (GTK_MINOR_VERSION == 0)
2300 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2304 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2305 #if 0 // unused - if this is ok, just remove this line (VZ)
2306 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2309 GtkWidget
*viewport
= scroll_window
->viewport
;
2310 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2312 dw
+= 2 * viewport_class
->xthickness
;
2313 dh
+= 2 * viewport_class
->ythickness
;
2317 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2319 /* when using GTK 1.2 we set the shadow border size to 2 */
2323 if (HasFlag(wxSIMPLE_BORDER
))
2325 /* when using GTK 1.2 we set the simple border size to 1 */
2334 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2335 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2337 we use this instead: range.slider_width = 11 + 2*2pts edge
2340 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2341 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2343 if (scroll_window
->vscrollbar_visible
)
2345 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2346 dw
+= scroll_class
->scrollbar_spacing
;
2349 if (scroll_window
->hscrollbar_visible
)
2351 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2352 dh
+= scroll_class
->scrollbar_spacing
;
2356 SetSize( width
+dw
, height
+dh
);
2360 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2362 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2366 if (width
) (*width
) = m_width
;
2367 if (height
) (*height
) = m_height
;
2374 #if (GTK_MINOR_VERSION == 0)
2375 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2379 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2380 #if 0 // unused - if this is ok, just remove this line (VZ)
2381 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2384 GtkWidget
*viewport
= scroll_window
->viewport
;
2385 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2387 dw
+= 2 * viewport_class
->xthickness
;
2388 dh
+= 2 * viewport_class
->ythickness
;
2392 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2394 /* when using GTK 1.2 we set the shadow border size to 2 */
2398 if (HasFlag(wxSIMPLE_BORDER
))
2400 /* when using GTK 1.2 we set the simple border size to 1 */
2408 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2409 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2411 we use this instead: range.slider_width = 11 + 2*2pts edge
2414 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2415 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2417 if (scroll_window
->vscrollbar_visible
)
2419 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2420 dw
+= scroll_class
->scrollbar_spacing
;
2423 if (scroll_window
->hscrollbar_visible
)
2425 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2426 dh
+= scroll_class
->scrollbar_spacing
;
2430 if (width
) (*width
) = m_width
- dw
;
2431 if (height
) (*height
) = m_height
- dh
;
2435 void wxWindow::DoGetPosition( int *x
, int *y
) const
2437 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2441 if (m_parent
&& m_parent
->m_wxwindow
)
2443 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_parent
->m_wxwindow
);
2444 dx
= myfixed
->xoffset
;
2445 dy
= myfixed
->yoffset
;
2448 if (x
) (*x
) = m_x
- dx
;
2449 if (y
) (*y
) = m_y
- dy
;
2452 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2454 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2456 if (!m_widget
->window
) return;
2458 GdkWindow
*source
= (GdkWindow
*) NULL
;
2460 source
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2462 source
= m_widget
->window
;
2466 gdk_window_get_origin( source
, &org_x
, &org_y
);
2470 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2472 org_x
+= m_widget
->allocation
.x
;
2473 org_y
+= m_widget
->allocation
.y
;
2481 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2483 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2485 if (!m_widget
->window
) return;
2487 GdkWindow
*source
= (GdkWindow
*) NULL
;
2489 source
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2491 source
= m_widget
->window
;
2495 gdk_window_get_origin( source
, &org_x
, &org_y
);
2499 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2501 org_x
+= m_widget
->allocation
.x
;
2502 org_y
+= m_widget
->allocation
.y
;
2510 bool wxWindow::Show( bool show
)
2512 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2514 if (!wxWindowBase::Show(show
))
2521 gtk_widget_show( m_widget
);
2523 gtk_widget_hide( m_widget
);
2528 bool wxWindow::Enable( bool enable
)
2530 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2532 if (!wxWindowBase::Enable(enable
))
2538 gtk_widget_set_sensitive( m_widget
, enable
);
2540 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2545 int wxWindow::GetCharHeight() const
2547 wxCHECK_MSG( (m_widget
!= NULL
), 12, wxT("invalid window") );
2549 wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") );
2551 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2553 return font
->ascent
+ font
->descent
;
2556 int wxWindow::GetCharWidth() const
2558 wxCHECK_MSG( (m_widget
!= NULL
), 8, wxT("invalid window") );
2560 wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") );
2562 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2564 return gdk_string_width( font
, "H" );
2567 void wxWindow::GetTextExtent( const wxString
& string
,
2571 int *externalLeading
,
2572 const wxFont
*theFont
) const
2574 wxFont fontToUse
= m_font
;
2575 if (theFont
) fontToUse
= *theFont
;
2577 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
2579 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2580 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2581 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2582 if (descent
) (*descent
) = font
->descent
;
2583 if (externalLeading
) (*externalLeading
) = 0; // ??
2586 void wxWindow::SetFocus()
2588 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2590 GtkWidget
*connect_widget
= GetConnectWidget();
2593 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2595 gtk_widget_grab_focus (connect_widget
);
2597 else if (GTK_IS_CONTAINER(connect_widget
))
2599 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2607 bool wxWindow::AcceptsFocus() const
2609 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2612 bool wxWindow::Reparent( wxWindowBase
*newParentBase
)
2614 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2616 wxWindow
*oldParent
= m_parent
,
2617 *newParent
= (wxWindow
*)newParentBase
;
2619 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2621 if ( !wxWindowBase::Reparent(newParent
) )
2624 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2626 /* prevent GTK from deleting the widget arbitrarily */
2627 gtk_widget_ref( m_widget
);
2631 gtk_container_remove( GTK_CONTAINER(oldParent
->m_wxwindow
), m_widget
);
2634 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2638 /* insert GTK representation */
2639 (*(newParent
->m_insertCallback
))(newParent
, this);
2642 /* reverse: prevent GTK from deleting the widget arbitrarily */
2643 gtk_widget_unref( m_widget
);
2648 void wxWindow::DoAddChild(wxWindow
*child
)
2650 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2652 wxASSERT_MSG( (child
!= NULL
), wxT("invalid child window") );
2654 wxASSERT_MSG( (m_insertCallback
!= NULL
), wxT("invalid child insertion function") );
2659 /* insert GTK representation */
2660 (*m_insertCallback
)(this, child
);
2663 void wxWindow::Raise()
2665 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2667 if (!m_widget
->window
) return;
2669 gdk_window_raise( m_widget
->window
);
2672 void wxWindow::Lower()
2674 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2676 if (!m_widget
->window
) return;
2678 gdk_window_lower( m_widget
->window
);
2681 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2683 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2685 return wxWindowBase::SetCursor( cursor
);
2688 void wxWindow::WarpPointer( int x
, int y
)
2690 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2692 /* we provide this function ourselves as it is
2693 missing in GDK (top of this file) */
2695 GdkWindow
*window
= (GdkWindow
*) NULL
;
2697 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2699 window
= GetConnectWidget()->window
;
2702 gdk_window_warp_pointer( window
, x
, y
);
2705 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2707 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2709 if (!m_widget
->window
) return;
2711 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2715 gdk_window_clear_area( GTK_MYFIXED(m_wxwindow
)->bin_window
,
2717 rect
->width
, rect
->height
);
2721 gdk_window_clear( GTK_MYFIXED(m_wxwindow
)->bin_window
);
2725 /* there is no GTK equivalent of "draw only, don't clear" so we
2726 invent our own in the GtkMyFixed widget */
2732 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
2733 gboolean old_clear
= myfixed
->clear_on_draw
;
2734 gtk_my_fixed_set_clear( myfixed
, FALSE
);
2736 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2738 gtk_my_fixed_set_clear( myfixed
, old_clear
);
2741 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2745 GdkRectangle gdk_rect
;
2746 gdk_rect
.x
= rect
->x
;
2747 gdk_rect
.y
= rect
->y
;
2748 gdk_rect
.width
= rect
->width
;
2749 gdk_rect
.height
= rect
->height
;
2753 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
2754 gboolean old_clear
= myfixed
->clear_on_draw
;
2755 gtk_my_fixed_set_clear( myfixed
, FALSE
);
2757 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2759 gtk_my_fixed_set_clear( myfixed
, old_clear
);
2762 gtk_widget_draw( m_widget
, &gdk_rect
);
2766 void wxWindow::Clear()
2768 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2770 if (!m_widget
->window
) return;
2772 if (m_wxwindow
&& m_wxwindow
->window
)
2774 gdk_window_clear( m_wxwindow
->window
);
2779 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2781 wxWindowBase::DoSetToolTip(tip
);
2784 m_tooltip
->Apply( this );
2787 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2789 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2791 #endif // wxUSE_TOOLTIPS
2793 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2795 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2797 if (!wxWindowBase::SetBackgroundColour(colour
))
2799 // don't leave if the GTK widget has just
2801 if (!m_delayedBackgroundColour
) return FALSE
;
2804 GdkWindow
*window
= (GdkWindow
*) NULL
;
2806 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2808 window
= GetConnectWidget()->window
;
2812 // indicate that a new style has been set
2813 // but it couldn't get applied as the
2814 // widget hasn't been realized yet.
2815 m_delayedBackgroundColour
= TRUE
;
2817 // pretend we have done something
2823 /* wxMSW doesn't clear the window here. I don't do that either to
2824 provide compatibility. call Clear() to do the job. */
2826 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2827 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2830 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2831 if (sysbg
== m_backgroundColour
)
2833 m_backgroundColour
= wxNullColour
;
2835 m_backgroundColour
= sysbg
;
2845 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2847 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2849 if (!wxWindowBase::SetForegroundColour(colour
))
2851 // don't leave if the GTK widget has just
2853 if (!m_delayedForegroundColour
) return FALSE
;
2856 GdkWindow
*window
= (GdkWindow
*) NULL
;
2858 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
2860 window
= GetConnectWidget()->window
;
2864 // indicate that a new style has been set
2865 // but it couldn't get applied as the
2866 // widget hasn't been realized yet.
2867 m_delayedForegroundColour
= TRUE
;
2869 // pretend we have done something
2873 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2874 if ( sysbg
== m_backgroundColour
)
2876 m_backgroundColour
= wxNullColour
;
2878 m_backgroundColour
= sysbg
;
2888 GtkStyle
*wxWindow::GetWidgetStyle()
2890 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2892 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2894 return m_widgetStyle
;
2897 void wxWindow::SetWidgetStyle()
2899 GtkStyle
*style
= GetWidgetStyle();
2901 gdk_font_unref( style
->font
);
2902 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2904 if (m_foregroundColour
.Ok())
2906 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2907 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2908 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2909 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2912 if (m_backgroundColour
.Ok())
2914 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2915 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2916 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2917 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2918 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2919 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2920 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2921 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2922 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2926 void wxWindow::ApplyWidgetStyle()
2930 //-----------------------------------------------------------------------------
2931 // Pop-up menu stuff
2932 //-----------------------------------------------------------------------------
2934 static void gtk_pop_hide_callback( GtkWidget
*WXUNUSED(widget
), bool* is_waiting
)
2936 *is_waiting
= FALSE
;
2939 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2941 menu
->SetInvokingWindow( win
);
2942 wxNode
*node
= menu
->GetItems().First();
2945 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2946 if (menuitem
->IsSubMenu())
2948 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2950 node
= node
->Next();
2954 static gint gs_pop_x
= 0;
2955 static gint gs_pop_y
= 0;
2957 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2961 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2966 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
2968 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2970 wxCHECK_MSG( menu
!= NULL
, FALSE
, wxT("invalid popup-menu") );
2972 SetInvokingWindow( menu
, this );
2979 bool is_waiting
= TRUE
;
2981 gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide",
2982 GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting
);
2985 GTK_MENU(menu
->m_menu
),
2986 (GtkWidget
*) NULL
, // parent menu shell
2987 (GtkWidget
*) NULL
, // parent menu item
2988 (GtkMenuPositionFunc
) pop_pos_callback
,
2989 (gpointer
) this, // client data
2990 0, // button used to activate it
2991 gs_timeLastClick
// the time of activation
2996 while (gtk_events_pending())
2997 gtk_main_iteration();
3003 #if wxUSE_DRAG_AND_DROP
3005 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
3007 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3009 GtkWidget
*dnd_widget
= GetConnectWidget();
3011 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
3013 if (m_dropTarget
) delete m_dropTarget
;
3014 m_dropTarget
= dropTarget
;
3016 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
3019 #endif // wxUSE_DRAG_AND_DROP
3021 GtkWidget
* wxWindow::GetConnectWidget()
3023 GtkWidget
*connect_widget
= m_widget
;
3024 if (m_wxwindow
) connect_widget
= m_wxwindow
;
3026 return connect_widget
;
3029 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
3032 return (window
== GTK_MYFIXED(m_wxwindow
)->bin_window
);
3034 return (window
== m_widget
->window
);
3037 bool wxWindow::SetFont( const wxFont
&font
)
3039 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
3041 if (!wxWindowBase::SetFont(font
))
3043 // don't leave if the GTK widget has just
3045 if (!m_delayedFont
) return FALSE
;
3048 GdkWindow
*window
= (GdkWindow
*) NULL
;
3050 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
3052 window
= GetConnectWidget()->window
;
3056 // indicate that a new style has been set
3057 // but it couldn't get applied as the
3058 // widget hasn't been realized yet.
3059 m_delayedFont
= TRUE
;
3061 // pretend we have done something
3065 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
3066 if ( sysbg
== m_backgroundColour
)
3068 m_backgroundColour
= wxNullColour
;
3070 m_backgroundColour
= sysbg
;
3080 void wxWindow::CaptureMouse()
3082 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3084 wxCHECK_RET( g_captureWindow
== NULL
, wxT("CaptureMouse called twice") );
3086 GdkWindow
*window
= (GdkWindow
*) NULL
;
3088 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
3090 window
= GetConnectWidget()->window
;
3092 if (!window
) return;
3094 gdk_pointer_grab( window
, FALSE
,
3096 (GDK_BUTTON_PRESS_MASK
|
3097 GDK_BUTTON_RELEASE_MASK
|
3098 GDK_POINTER_MOTION_HINT_MASK
|
3099 GDK_POINTER_MOTION_MASK
),
3101 m_cursor
.GetCursor(),
3103 g_captureWindow
= this;
3106 void wxWindow::ReleaseMouse()
3108 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3110 wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") );
3112 GdkWindow
*window
= (GdkWindow
*) NULL
;
3114 window
= GTK_MYFIXED(m_wxwindow
)->bin_window
;
3116 window
= GetConnectWidget()->window
;
3118 if (!window
) return;
3120 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3121 g_captureWindow
= (wxWindow
*) NULL
;
3124 bool wxWindow::IsRetained() const
3129 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3130 int range
, bool refresh
)
3132 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3134 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3136 m_hasScrolling
= TRUE
;
3138 if (orient
== wxHORIZONTAL
)
3140 float fpos
= (float)pos
;
3141 float frange
= (float)range
;
3142 float fthumb
= (float)thumbVisible
;
3143 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3144 if (fpos
< 0.0) fpos
= 0.0;
3146 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3147 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3149 SetScrollPos( orient
, pos
, refresh
);
3153 m_oldHorizontalPos
= fpos
;
3155 m_hAdjust
->lower
= 0.0;
3156 m_hAdjust
->upper
= frange
;
3157 m_hAdjust
->value
= fpos
;
3158 m_hAdjust
->step_increment
= 1.0;
3159 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3160 m_hAdjust
->page_size
= fthumb
;
3164 float fpos
= (float)pos
;
3165 float frange
= (float)range
;
3166 float fthumb
= (float)thumbVisible
;
3167 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3168 if (fpos
< 0.0) fpos
= 0.0;
3170 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3171 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3173 SetScrollPos( orient
, pos
, refresh
);
3177 m_oldVerticalPos
= fpos
;
3179 m_vAdjust
->lower
= 0.0;
3180 m_vAdjust
->upper
= frange
;
3181 m_vAdjust
->value
= fpos
;
3182 m_vAdjust
->step_increment
= 1.0;
3183 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3184 m_vAdjust
->page_size
= fthumb
;
3187 if (orient
== wxHORIZONTAL
)
3188 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3190 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3193 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3195 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3197 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3199 if (orient
== wxHORIZONTAL
)
3201 float fpos
= (float)pos
;
3202 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3203 if (fpos
< 0.0) fpos
= 0.0;
3204 m_oldHorizontalPos
= fpos
;
3206 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3207 m_hAdjust
->value
= fpos
;
3211 float fpos
= (float)pos
;
3212 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3213 if (fpos
< 0.0) fpos
= 0.0;
3214 m_oldVerticalPos
= fpos
;
3216 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3217 m_vAdjust
->value
= fpos
;
3224 if (m_wxwindow
->window
)
3226 if (orient
== wxHORIZONTAL
)
3227 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3229 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3236 int wxWindow::GetScrollThumb( int orient
) const
3238 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3240 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3242 if (orient
== wxHORIZONTAL
)
3243 return (int)(m_hAdjust
->page_size
+0.5);
3245 return (int)(m_vAdjust
->page_size
+0.5);
3248 int wxWindow::GetScrollPos( int orient
) const
3250 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3252 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3254 if (orient
== wxHORIZONTAL
)
3255 return (int)(m_hAdjust
->value
+0.5);
3257 return (int)(m_vAdjust
->value
+0.5);
3260 int wxWindow::GetScrollRange( int orient
) const
3262 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3264 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3266 if (orient
== wxHORIZONTAL
)
3267 return (int)(m_hAdjust
->upper
+0.5);
3269 return (int)(m_vAdjust
->upper
+0.5);
3272 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3274 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3276 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3278 gtk_myfixed_scroll( GTK_MYFIXED(m_wxwindow
), -dx
, -dy
);
3283 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3284 gdk_gc_set_exposures( m_scrollGC, TRUE );
3287 wxNode *node = m_children.First();
3290 wxWindow *child = (wxWindow*) node->Data();
3293 child->GetSize( &sx, &sy );
3294 child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
3295 node = node->Next();
3300 GetClientSize( &cw, &ch );
3301 int w = cw - abs(dx);
3302 int h = ch - abs(dy);
3304 if ((h < 0) || (w < 0))
3312 if (dx < 0) s_x = -dx;
3313 if (dy < 0) s_y = -dy;
3316 if (dx > 0) d_x = dx;
3317 if (dy > 0) d_y = dy;
3319 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
3320 m_wxwindow->window, s_x, s_y, w, h );
3323 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3324 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3325 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3326 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
3328 Refresh( TRUE, &rect );
3333 void wxWindow::SetScrolling(bool scroll
)
3335 m_isScrolling
= g_blockEventsOnScroll
= scroll
;