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.
62 What does wxWindow do? It contains the common interface for the following
63 jobs of its descendants:
65 1) Define the rudimentary behaviour common to all window classes, such as
66 resizing, intercepting user input (so as to make it possible to use these
67 events for special purposes in a derived class), window names etc.
69 2) Provide the possibility to contain and manage children, if the derived
70 class is allowed to contain children, which holds true for those window
71 classes which do not display a native GTK widget. To name them, these
72 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
73 work classes are a special case and are handled a bit differently from
74 the rest. The same holds true for the wxNotebook class.
76 3) Provide the possibility to draw into a client area of a window. This,
77 too, only holds true for classes that do not display a native GTK widget
80 4) Provide the entire mechanism for scrolling widgets. This actual inter-
81 face for this is usually in wxScrolledWindow, but the GTK implementation
84 5) A multitude of helper or extra methods for special purposes, such as
85 Drag'n'Drop, managing validators etc.
87 6) Display a border (sunken, raised, simple or none).
89 Normally one might expect, that one wxWindows window would always correspond
90 to one GTK widget. Under GTK, there is no such allround widget that has all
91 the functionality. Moreover, the GTK defines a client area as a different
92 widget from the actual widget you are handling. Last but not least some
93 special classes (e.g. wxFrame) handle different categories of widgets and
94 still have the possibility to draw something in the client area.
95 It was therefore required to write a special purpose GTK widget, that would
96 represent a client area in the sense of wxWindows capable to do the jobs
97 2), 3) and 4). I have written this class and it resides in win_gtk.c of
100 All windows must have a widget, with which they interact with other under-
101 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
102 thw wxWindow class has a member variable called m_widget which holds a
103 pointer to this widget. When the window class represents a GTK native widget,
104 this is (in most cases) the only GTK widget the class manages. E.g. the
105 wxStatitText class handles only a GtkLabel widget a pointer to which you
106 can find in m_widget (defined in wxWindow)
108 When the class has a client area for drawing into and for containing children
109 it has to handle the client area widget (of the type GtkPizza, defined in
110 win_gtk.c), but there could be any number of widgets, handled by a class
111 The common rule for all windows is only, that the widget that interacts with
112 the rest of GTK must be referenced in m_widget and all other widgets must be
113 children of this widget on the GTK level. The top-most widget, which also
114 represents the client area, must be in the m_wxwindow field and must be of
117 As I said, the window classes that display a GTK native widget only have
118 one widget, so in the case of e.g. the wxButton class m_widget holds a
119 pointer to a GtkButton widget. But windows with client areas (for drawing
120 and children) have a m_widget field that is a pointer to a GtkScrolled-
121 Window and a m_wxwindow field that is pointer to a GtkPizza and this
122 one is (in the GTK sense) a child of the GtkScrolledWindow.
124 If the m_wxwindow field is set, then all input to this widget is inter-
125 cepted and sent to the wxWindows class. If not, all input to the widget
126 that gets pointed to by m_widget gets intercepted and sent to the class.
130 The design of scrolling in wxWindows is markedly different from that offered
131 by the GTK itself and therefore we cannot simply take it as it is. In GTK,
132 clicking on a scrollbar belonging to scrolled window will inevitably move
133 the window. In wxWindows, the scrollbar will only emit an event, send this
134 to (normally) a wxScrolledWindow and that class will call ScrollWindow()
135 which actually moves the window and its subchildren. Note that GtkPizza
136 memorizes how much it has been scrolled but that wxWindows forgets this
137 so that the two coordinates systems have to be kept in synch. This is done
138 in various places using the pizza->xoffset and pizza->yoffset values.
142 Singularily the most broken code in GTK is the code that is supposes to
143 inform subwindows (child windows) about new positions. Very often, duplicate
144 events are sent without changes in size or position, equally often no
145 events are sent at all (All this is due to a bug in the GtkContainer code
146 which got fixed in GTK 1.2.6). For that reason, wxGTK completely ignores
147 GTK's own system and it simply waits for size events for toplevel windows
148 and then iterates down the respective size events to all window. This has
149 the disadvantage, that windows might get size events before the GTK widget
150 actually has the reported size. This doesn't normally pose any problem, but
151 the OpenGl drawing routines rely on correct behaviour. Therefore, I have
152 added the m_nativeSizeEvents flag, which is true only for the OpenGL canvas,
153 i.e. the wxGLCanvas will emit a size event, when (and not before) the X11
154 window that is used for OpenGl output really has that size (as reported by
159 If someone at some point of time feels the immense desire to have a look at,
160 change or attempt to optimse the Refresh() logic, this person will need an
161 intimate understanding of what a "draw" and what an "expose" events are and
162 what there are used for, in particular when used in connection with GTK's
163 own windowless widgets. Beware.
167 Cursors, too, have been a constant source of pleasure. The main difficulty
168 is that a GdkWindow inherits a cursor if the programmer sets a new cursor
169 for the parent. To prevent this from doing too much harm, I use idle time
170 to set the cursor over and over again, starting from the toplevel windows
171 and ending with the youngest generation (speaking of parent and child windows).
172 Also don't forget that cursors (like much else) are connected to GdkWindows,
173 not GtkWidgets and that the "window" field of a GtkWidget might very well
174 point to the GdkWindow of the parent widget (-> "window less widget") and
175 that the two obviously have very different meanings.
179 //-----------------------------------------------------------------------------
181 //-----------------------------------------------------------------------------
183 extern wxList wxPendingDelete
;
184 extern bool g_blockEventsOnDrag
;
185 extern bool g_blockEventsOnScroll
;
186 extern wxCursor g_globalCursor
;
187 static wxWindow
*g_captureWindow
= (wxWindow
*) NULL
;
189 /* extern */ wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
191 // if we detect that the app has got/lost the focus, we set this variable to
192 // either TRUE or FALSE and an activate event will be sent during the next
193 // OnIdle() call and it is reset to -1: this value means that we shouldn't
194 // send any activate events at all
195 static int g_sendActivateEvent
= -1;
197 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
198 the last click here */
199 static guint32 gs_timeLastClick
= 0;
201 //-----------------------------------------------------------------------------
203 //-----------------------------------------------------------------------------
207 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
208 GdkEvent
*WXUNUSED(event
),
209 const wxChar
*WXUNUSED(name
) )
212 static bool s_done = FALSE;
215 wxLog::AddTraceMask("focus");
218 wxLogTrace(wxT("FOCUS NOW AT: %s"), name);
224 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
226 // suppress warnings about gtk_debug_focus_in_callback being unused with
231 tmp
+= wxT(" FROM ");
234 wxChar
*s
= new wxChar
[tmp
.Length()+1];
238 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
239 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
245 //-----------------------------------------------------------------------------
246 // missing gdk functions
247 //-----------------------------------------------------------------------------
250 gdk_window_warp_pointer (GdkWindow
*window
,
254 GdkWindowPrivate
*priv
;
257 window
= (GdkWindow
*) &gdk_root_parent
;
259 priv
= (GdkWindowPrivate
*) window
;
261 if (!priv
->destroyed
)
263 XWarpPointer (priv
->xdisplay
,
264 None
, /* not source window -> move from anywhere */
265 priv
->xwindow
, /* dest window */
266 0, 0, 0, 0, /* not source window -> move from anywhere */
271 //-----------------------------------------------------------------------------
273 //-----------------------------------------------------------------------------
275 extern void wxapp_install_idle_handler();
276 extern bool g_isIdle
;
278 //-----------------------------------------------------------------------------
279 // local code (see below)
280 //-----------------------------------------------------------------------------
282 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
290 if (win
->HasScrolling())
292 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
293 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
296 GtkWidget *hscrollbar = scroll_window->hscrollbar;
297 GtkWidget *vscrollbar = scroll_window->vscrollbar;
299 we use this instead: range.slider_width = 11 + 2*2pts edge
302 if (scroll_window
->vscrollbar_visible
)
304 dw
+= 15; /* dw += vscrollbar->allocation.width; */
305 dw
+= scroll_class
->scrollbar_spacing
;
308 if (scroll_window
->hscrollbar_visible
)
310 dh
+= 15; /* dh += hscrollbar->allocation.height; */
311 dh
+= scroll_class
->scrollbar_spacing
;
317 if (GTK_WIDGET_NO_WINDOW (widget
))
319 dx
+= widget
->allocation
.x
;
320 dy
+= widget
->allocation
.y
;
323 if (win
->HasFlag(wxRAISED_BORDER
))
325 gtk_draw_shadow( widget
->style
,
330 widget
->allocation
.width
-dw
, widget
->allocation
.height
-dh
);
334 if (win
->HasFlag(wxSUNKEN_BORDER
))
336 gtk_draw_shadow( widget
->style
,
341 widget
->allocation
.width
-dw
, widget
->allocation
.height
-dh
);
345 if (win
->HasFlag(wxSIMPLE_BORDER
))
348 gc
= gdk_gc_new( widget
->window
);
349 gdk_gc_set_foreground( gc
, &widget
->style
->black
);
350 gdk_draw_rectangle( widget
->window
, gc
, FALSE
,
352 widget
->allocation
.width
-dw
-1, widget
->allocation
.height
-dh
-1 );
358 //-----------------------------------------------------------------------------
359 // "expose_event" of m_widget
360 //-----------------------------------------------------------------------------
362 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
364 if (gdk_event
->count
> 0) return;
365 draw_frame( widget
, win
);
368 //-----------------------------------------------------------------------------
369 // "draw" of m_widget
370 //-----------------------------------------------------------------------------
372 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
374 draw_frame( widget
, win
);
377 //-----------------------------------------------------------------------------
378 // key code mapping routines
379 //-----------------------------------------------------------------------------
381 static long map_to_unmodified_wx_keysym( KeySym keysym
)
388 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
390 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
396 case GDK_Super_R
: key_code
= WXK_ALT
; break;
397 case GDK_Menu
: key_code
= WXK_MENU
; break;
398 case GDK_Help
: key_code
= WXK_HELP
; break;
399 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
400 case GDK_ISO_Left_Tab
:
401 case GDK_Tab
: key_code
= WXK_TAB
; break;
402 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
403 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
404 case GDK_Return
: key_code
= WXK_RETURN
; break;
405 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
406 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
407 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
408 case GDK_Delete
: key_code
= WXK_DELETE
; break;
409 case GDK_Home
: key_code
= WXK_HOME
; break;
410 case GDK_Left
: key_code
= WXK_LEFT
; break;
411 case GDK_Up
: key_code
= WXK_UP
; break;
412 case GDK_Right
: key_code
= WXK_RIGHT
; break;
413 case GDK_Down
: key_code
= WXK_DOWN
; break;
414 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
415 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
416 case GDK_Next
: key_code
= WXK_NEXT
; break;
417 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
418 case GDK_End
: key_code
= WXK_END
; break;
419 case GDK_Begin
: key_code
= WXK_HOME
; break;
420 case GDK_Select
: key_code
= WXK_SELECT
; break;
421 case GDK_Print
: key_code
= WXK_PRINT
; break;
422 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
423 case GDK_Insert
: key_code
= WXK_INSERT
; break;
424 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
426 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
427 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
428 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
429 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
430 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
431 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
432 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
433 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
434 case GDK_KP_8
: key_code
= WXK_NUMPAD8
; break;
435 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
436 case GDK_KP_Space
: key_code
= WXK_NUMPAD_SPACE
; break;
437 case GDK_KP_Tab
: key_code
= WXK_NUMPAD_TAB
; break;
438 case GDK_KP_Enter
: key_code
= WXK_NUMPAD_ENTER
; break;
439 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
440 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
441 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
442 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
443 case GDK_KP_Home
: key_code
= WXK_NUMPAD_HOME
; break;
444 case GDK_KP_Left
: key_code
= WXK_NUMPAD_LEFT
; break;
445 case GDK_KP_Up
: key_code
= WXK_NUMPAD_UP
; break;
446 case GDK_KP_Right
: key_code
= WXK_NUMPAD_RIGHT
; break;
447 case GDK_KP_Down
: key_code
= WXK_NUMPAD_DOWN
; break;
448 case GDK_KP_Prior
: key_code
= WXK_NUMPAD_PRIOR
; break;
449 // case GDK_KP_Page_Up: key_code = WXK_NUMPAD_PAGEUP; break;
450 case GDK_KP_Next
: key_code
= WXK_NUMPAD_NEXT
; break;
451 // case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break;
452 case GDK_KP_End
: key_code
= WXK_NUMPAD_END
; break;
453 case GDK_KP_Begin
: key_code
= WXK_NUMPAD_BEGIN
; break;
454 case GDK_KP_Insert
: key_code
= WXK_NUMPAD_INSERT
; break;
455 case GDK_KP_Delete
: key_code
= WXK_NUMPAD_DELETE
; break;
456 case GDK_KP_Equal
: key_code
= WXK_NUMPAD_EQUAL
; break;
457 case GDK_KP_Multiply
: key_code
= WXK_NUMPAD_MULTIPLY
; break;
458 case GDK_KP_Add
: key_code
= WXK_NUMPAD_ADD
; break;
459 case GDK_KP_Separator
: key_code
= WXK_NUMPAD_SEPARATOR
; break;
460 case GDK_KP_Subtract
: key_code
= WXK_NUMPAD_SUBTRACT
; break;
461 case GDK_KP_Decimal
: key_code
= WXK_NUMPAD_DECIMAL
; break;
462 case GDK_KP_Divide
: key_code
= WXK_NUMPAD_DIVIDE
; break;
464 case GDK_F1
: key_code
= WXK_F1
; break;
465 case GDK_F2
: key_code
= WXK_F2
; break;
466 case GDK_F3
: key_code
= WXK_F3
; break;
467 case GDK_F4
: key_code
= WXK_F4
; break;
468 case GDK_F5
: key_code
= WXK_F5
; break;
469 case GDK_F6
: key_code
= WXK_F6
; break;
470 case GDK_F7
: key_code
= WXK_F7
; break;
471 case GDK_F8
: key_code
= WXK_F8
; break;
472 case GDK_F9
: key_code
= WXK_F9
; break;
473 case GDK_F10
: key_code
= WXK_F10
; break;
474 case GDK_F11
: key_code
= WXK_F11
; break;
475 case GDK_F12
: key_code
= WXK_F12
; break;
480 guint upper
= gdk_keyval_to_upper( (guint
)keysym
);
481 keysym
= (upper
!= 0 ? upper
: keysym
); /* to be MSW compatible */
482 key_code
= (guint
)keysym
;
490 static long map_to_wx_keysym( KeySym keysym
)
496 case GDK_Menu
: key_code
= WXK_MENU
; break;
497 case GDK_Help
: key_code
= WXK_HELP
; break;
498 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
499 case GDK_ISO_Left_Tab
:
500 case GDK_Tab
: key_code
= WXK_TAB
; break;
501 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
502 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
503 case GDK_Return
: key_code
= WXK_RETURN
; break;
504 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
505 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
506 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
507 case GDK_Delete
: key_code
= WXK_DELETE
; break;
508 case GDK_Home
: key_code
= WXK_HOME
; break;
509 case GDK_Left
: key_code
= WXK_LEFT
; break;
510 case GDK_Up
: key_code
= WXK_UP
; break;
511 case GDK_Right
: key_code
= WXK_RIGHT
; break;
512 case GDK_Down
: key_code
= WXK_DOWN
; break;
513 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
514 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
515 case GDK_Next
: key_code
= WXK_NEXT
; break;
516 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
517 case GDK_End
: key_code
= WXK_END
; break;
518 case GDK_Begin
: key_code
= WXK_HOME
; break;
519 case GDK_Select
: key_code
= WXK_SELECT
; break;
520 case GDK_Print
: key_code
= WXK_PRINT
; break;
521 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
522 case GDK_Insert
: key_code
= WXK_INSERT
; break;
523 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
525 case GDK_KP_0
: key_code
= '0'; break;
526 case GDK_KP_1
: key_code
= '1'; break;
527 case GDK_KP_2
: key_code
= '2'; break;
528 case GDK_KP_3
: key_code
= '3'; break;
529 case GDK_KP_4
: key_code
= '4'; break;
530 case GDK_KP_5
: key_code
= '5'; break;
531 case GDK_KP_6
: key_code
= '6'; break;
532 case GDK_KP_7
: key_code
= '7'; break;
533 case GDK_KP_8
: key_code
= '8'; break;
534 case GDK_KP_9
: key_code
= '9'; break;
535 case GDK_KP_Space
: key_code
= ' '; break;
536 case GDK_KP_Tab
: key_code
= WXK_TAB
; break; /* or '\t' ??? */
537 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break; /* or '\r' ??? */
538 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
539 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
540 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
541 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
542 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
543 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
544 case GDK_KP_Up
: key_code
= WXK_UP
; break;
545 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
546 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
547 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
548 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
549 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
550 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
551 case GDK_KP_End
: key_code
= WXK_END
; break;
552 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
553 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
554 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
555 case GDK_KP_Equal
: key_code
= '='; break;
556 case GDK_KP_Multiply
: key_code
= '*'; break;
557 case GDK_KP_Add
: key_code
= '+'; break;
558 case GDK_KP_Separator
: key_code
= ','; break;
559 case GDK_KP_Subtract
: key_code
= '-'; break;
560 case GDK_KP_Decimal
: key_code
= '.'; break;
561 case GDK_KP_Divide
: key_code
= '/'; break;
563 case GDK_F1
: key_code
= WXK_F1
; break;
564 case GDK_F2
: key_code
= WXK_F2
; break;
565 case GDK_F3
: key_code
= WXK_F3
; break;
566 case GDK_F4
: key_code
= WXK_F4
; break;
567 case GDK_F5
: key_code
= WXK_F5
; break;
568 case GDK_F6
: key_code
= WXK_F6
; break;
569 case GDK_F7
: key_code
= WXK_F7
; break;
570 case GDK_F8
: key_code
= WXK_F8
; break;
571 case GDK_F9
: key_code
= WXK_F9
; break;
572 case GDK_F10
: key_code
= WXK_F10
; break;
573 case GDK_F11
: key_code
= WXK_F11
; break;
574 case GDK_F12
: key_code
= WXK_F12
; break;
579 key_code
= (guint
)keysym
;
587 //-----------------------------------------------------------------------------
588 // "expose_event" of m_wxwindow
589 //-----------------------------------------------------------------------------
591 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
596 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
598 gdk_event
->area
.width
,
599 gdk_event
->area
.height
);
602 wxPrintf( "OnExpose from " );
603 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
604 wxPrintf( win->GetClassInfo()->GetClassName() );
605 wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x,
606 (int)gdk_event->area.y,
607 (int)gdk_event->area.width,
608 (int)gdk_event->area.height );
611 if (gdk_event
->count
> 0)
614 wxEraseEvent
eevent( win
->GetId() );
615 eevent
.SetEventObject( win
);
616 win
->GetEventHandler()->ProcessEvent(eevent
);
618 wxPaintEvent
event( win
->GetId() );
619 event
.SetEventObject( win
);
620 win
->GetEventHandler()->ProcessEvent( event
);
622 win
->GetUpdateRegion().Clear();
625 //-----------------------------------------------------------------------------
626 // "draw" of m_wxwindow
627 //-----------------------------------------------------------------------------
629 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
),
630 GdkRectangle
*rect
, wxWindow
*win
)
633 wxapp_install_idle_handler();
638 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
639 rect
->width
, rect
->height
);
642 wxPrintf( "OnDraw from " );
643 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
644 printf( win->GetClassInfo()->GetClassName() );
645 wxPrintf( " %d %d %d %d\n", (int)rect->x,
651 wxEraseEvent
eevent( win
->GetId() );
652 eevent
.SetEventObject( win
);
653 win
->GetEventHandler()->ProcessEvent(eevent
);
655 wxPaintEvent
event( win
->GetId() );
656 event
.SetEventObject( win
);
657 win
->GetEventHandler()->ProcessEvent( event
);
659 win
->GetUpdateRegion().Clear();
662 //-----------------------------------------------------------------------------
663 // "key_press_event" from any window
664 //-----------------------------------------------------------------------------
666 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
669 wxapp_install_idle_handler();
671 if (!win
->m_hasVMT
) return FALSE
;
672 if (g_blockEventsOnDrag
) return FALSE
;
676 tmp += (char)gdk_event->keyval;
677 printf( "KeyDown-Code is: %s.\n", tmp.c_str() );
678 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
683 GdkModifierType state
;
684 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
688 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
689 /* sending unknown key events doesn't really make sense */
690 if (key_code
== 0) return FALSE
;
692 wxKeyEvent
event( wxEVT_KEY_DOWN
);
693 event
.SetTimestamp( gdk_event
->time
);
694 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
695 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
696 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
697 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
698 event
.m_keyCode
= key_code
;
699 event
.m_scanCode
= gdk_event
->keyval
;
702 event
.SetEventObject( win
);
703 ret
= win
->GetEventHandler()->ProcessEvent( event
);
708 wxWindow
*ancestor
= win
;
711 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
714 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
715 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
718 if (ancestor
->m_isFrame
)
720 ancestor
= ancestor
->GetParent();
723 #endif // wxUSE_ACCEL
725 /* wxMSW doesn't send char events with Alt pressed */
726 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
727 will only be sent if it is not in an accelerator table. */
728 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
733 wxKeyEvent
event2( wxEVT_CHAR
);
734 event2
.SetTimestamp( gdk_event
->time
);
735 event2
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
736 event2
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
737 event2
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
738 event2
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
739 event2
.m_keyCode
= key_code
;
740 event2
.m_scanCode
= gdk_event
->keyval
;
743 event2
.SetEventObject( win
);
744 ret
= win
->GetEventHandler()->ProcessEvent( event2
);
747 /* win is a control: tab can be propagated up */
749 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
750 (!win
->HasFlag(wxTE_PROCESS_TAB
)) &&
751 (win
->GetParent()) &&
752 (win
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
754 wxNavigationKeyEvent new_event
;
755 new_event
.SetEventObject( win
);
756 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
757 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
758 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
759 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
760 new_event
.SetCurrentFocus( win
);
761 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
764 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
766 (gdk_event
->keyval
== GDK_Escape
) )
768 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
769 new_event
.SetEventObject( win
);
770 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
773 #if (GTK_MINOR_VERSION > 0)
774 /* Pressing F10 will activate the menu bar of the top frame. */
778 (gdk_event->keyval == GDK_F10) )
780 wxWindow *ancestor = win;
783 if (wxIsKindOf(ancestor,wxFrame))
785 wxFrame *frame = (wxFrame*) ancestor;
786 wxMenuBar *menubar = frame->GetMenuBar();
789 wxNode *node = menubar->GetMenus().First();
792 wxMenu *firstMenu = (wxMenu*) node->Data();
793 gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
799 ancestor = ancestor->GetParent();
807 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
814 //-----------------------------------------------------------------------------
815 // "key_release_event" from any window
816 //-----------------------------------------------------------------------------
818 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
821 wxapp_install_idle_handler();
823 if (!win
->m_hasVMT
) return FALSE
;
824 if (g_blockEventsOnDrag
) return FALSE
;
827 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
828 if (gdk_event->state & GDK_SHIFT_MASK)
829 printf( "ShiftDown.\n" );
831 printf( "ShiftUp.\n" );
832 if (gdk_event->state & GDK_CONTROL_MASK)
833 printf( "ControlDown.\n" );
835 printf( "ControlUp.\n" );
839 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
841 /* sending unknown key events doesn't really make sense */
842 if (key_code
== 0) return FALSE
;
846 GdkModifierType state
;
847 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
849 wxKeyEvent
event( wxEVT_KEY_UP
);
850 event
.SetTimestamp( gdk_event
->time
);
851 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
852 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
853 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
854 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
855 event
.m_keyCode
= key_code
;
856 event
.m_scanCode
= gdk_event
->keyval
;
859 event
.SetEventObject( win
);
861 if (win
->GetEventHandler()->ProcessEvent( event
))
863 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
870 //-----------------------------------------------------------------------------
871 // "button_press_event"
872 //-----------------------------------------------------------------------------
874 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
877 wxapp_install_idle_handler();
880 wxPrintf( wxT("1) OnButtonPress from ") );
881 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
882 wxPrintf( win->GetClassInfo()->GetClassName() );
883 wxPrintf( wxT(".\n") );
885 if (!win
->m_hasVMT
) return FALSE
;
886 if (g_blockEventsOnDrag
) return TRUE
;
887 if (g_blockEventsOnScroll
) return TRUE
;
889 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
893 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
895 gtk_widget_grab_focus (win
->m_wxwindow
);
898 wxPrintf( wxT("GrabFocus from ") );
899 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
900 wxPrintf( win->GetClassInfo()->GetClassName() );
901 wxPrintf( wxT(".\n") );
907 wxEventType event_type
= wxEVT_LEFT_DOWN
;
909 if (gdk_event
->button
== 1)
911 switch (gdk_event
->type
)
913 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
914 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
918 else if (gdk_event
->button
== 2)
920 switch (gdk_event
->type
)
922 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
923 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
927 else if (gdk_event
->button
== 3)
929 switch (gdk_event
->type
)
931 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
932 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
937 wxMouseEvent
event( event_type
);
938 event
.SetTimestamp( gdk_event
->time
);
939 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
940 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
941 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
942 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
943 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
944 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
945 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
947 event
.m_x
= (wxCoord
)gdk_event
->x
;
948 event
.m_y
= (wxCoord
)gdk_event
->y
;
950 // Some control don't have their own X window and thus cannot get
953 if (!g_captureWindow
)
955 wxCoord x
= event
.m_x
;
956 wxCoord y
= event
.m_y
;
959 GtkPizza
*pizza
= GTK_PIZZA(win
->m_wxwindow
);
964 wxNode
*node
= win
->GetChildren().First();
967 wxWindow
*child
= (wxWindow
*)node
->Data();
970 if (!child
->IsShown())
973 if (child
->m_isStaticBox
)
975 // wxStaticBox is transparent in the box itself
976 int xx1
= child
->m_x
;
977 int yy1
= child
->m_y
;
978 int xx2
= child
->m_x
+ child
->m_width
;
979 int yy2
= child
->m_x
+ child
->m_height
;
982 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
984 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
986 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
988 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
991 event
.m_x
-= child
->m_x
;
992 event
.m_y
-= child
->m_y
;
999 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1000 (child
->m_x
<= x
) &&
1001 (child
->m_y
<= y
) &&
1002 (child
->m_x
+child
->m_width
>= x
) &&
1003 (child
->m_y
+child
->m_height
>= y
))
1006 event
.m_x
-= child
->m_x
;
1007 event
.m_y
-= child
->m_y
;
1014 event
.SetEventObject( win
);
1016 gs_timeLastClick
= gdk_event
->time
;
1019 wxPrintf( wxT("2) OnButtonPress from ") );
1020 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1021 wxPrintf( win->GetClassInfo()->GetClassName() );
1022 wxPrintf( wxT(".\n") );
1025 if (win
->GetEventHandler()->ProcessEvent( event
))
1027 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
1034 //-----------------------------------------------------------------------------
1035 // "button_release_event"
1036 //-----------------------------------------------------------------------------
1038 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1041 wxapp_install_idle_handler();
1043 if (!win
->m_hasVMT
) return FALSE
;
1044 if (g_blockEventsOnDrag
) return FALSE
;
1045 if (g_blockEventsOnScroll
) return FALSE
;
1047 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1050 printf( "OnButtonRelease from " );
1051 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1052 printf( win->GetClassInfo()->GetClassName() );
1056 wxEventType event_type
= wxEVT_NULL
;
1058 switch (gdk_event
->button
)
1060 case 1: event_type
= wxEVT_LEFT_UP
; break;
1061 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
1062 case 3: event_type
= wxEVT_RIGHT_UP
; break;
1065 wxMouseEvent
event( event_type
);
1066 event
.SetTimestamp( gdk_event
->time
);
1067 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1068 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1069 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1070 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1071 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1072 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1073 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1074 event
.m_x
= (wxCoord
)gdk_event
->x
;
1075 event
.m_y
= (wxCoord
)gdk_event
->y
;
1077 // Some control don't have their own X window and thus cannot get
1080 if (!g_captureWindow
)
1082 wxCoord x
= event
.m_x
;
1083 wxCoord y
= event
.m_y
;
1084 if (win
->m_wxwindow
)
1086 GtkPizza
*pizza
= GTK_PIZZA(win
->m_wxwindow
);
1087 x
+= pizza
->xoffset
;
1088 y
+= pizza
->yoffset
;
1091 wxNode
*node
= win
->GetChildren().First();
1094 wxWindow
*child
= (wxWindow
*)node
->Data();
1096 node
= node
->Next();
1097 if (!child
->IsShown())
1100 if (child
->m_isStaticBox
)
1102 // wxStaticBox is transparent in the box itself
1103 int xx1
= child
->m_x
;
1104 int yy1
= child
->m_y
;
1105 int xx2
= child
->m_x
+ child
->m_width
;
1106 int yy2
= child
->m_x
+ child
->m_height
;
1109 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1111 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1113 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1115 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1118 event
.m_x
-= child
->m_x
;
1119 event
.m_y
-= child
->m_y
;
1126 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1127 (child
->m_x
<= x
) &&
1128 (child
->m_y
<= y
) &&
1129 (child
->m_x
+child
->m_width
>= x
) &&
1130 (child
->m_y
+child
->m_height
>= y
))
1133 event
.m_x
-= child
->m_x
;
1134 event
.m_y
-= child
->m_y
;
1141 event
.SetEventObject( win
);
1143 if (win
->GetEventHandler()->ProcessEvent( event
))
1145 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1152 //-----------------------------------------------------------------------------
1153 // "motion_notify_event"
1154 //-----------------------------------------------------------------------------
1156 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1159 wxapp_install_idle_handler();
1161 if (!win
->m_hasVMT
) return FALSE
;
1162 if (g_blockEventsOnDrag
) return FALSE
;
1163 if (g_blockEventsOnScroll
) return FALSE
;
1165 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1167 if (gdk_event
->is_hint
)
1171 GdkModifierType state
;
1172 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1178 printf( "OnMotion from " );
1179 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1180 printf( win->GetClassInfo()->GetClassName() );
1184 wxMouseEvent
event( wxEVT_MOTION
);
1185 event
.SetTimestamp( gdk_event
->time
);
1186 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1187 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1188 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1189 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1190 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1191 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1192 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1194 event
.m_x
= (wxCoord
)gdk_event
->x
;
1195 event
.m_y
= (wxCoord
)gdk_event
->y
;
1197 // Some control don't have their own X window and thus cannot get
1200 if (!g_captureWindow
)
1202 wxCoord x
= event
.m_x
;
1203 wxCoord y
= event
.m_y
;
1204 if (win
->m_wxwindow
)
1206 GtkPizza
*pizza
= GTK_PIZZA(win
->m_wxwindow
);
1207 x
+= pizza
->xoffset
;
1208 y
+= pizza
->yoffset
;
1211 wxNode
*node
= win
->GetChildren().First();
1214 wxWindow
*child
= (wxWindow
*)node
->Data();
1216 node
= node
->Next();
1217 if (!child
->IsShown())
1220 if (child
->m_isStaticBox
)
1222 // wxStaticBox is transparent in the box itself
1223 int xx1
= child
->m_x
;
1224 int yy1
= child
->m_y
;
1225 int xx2
= child
->m_x
+ child
->m_width
;
1226 int yy2
= child
->m_x
+ child
->m_height
;
1229 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1231 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1233 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1235 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1238 event
.m_x
-= child
->m_x
;
1239 event
.m_y
-= child
->m_y
;
1246 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1247 (child
->m_x
<= x
) &&
1248 (child
->m_y
<= y
) &&
1249 (child
->m_x
+child
->m_width
>= x
) &&
1250 (child
->m_y
+child
->m_height
>= y
))
1253 event
.m_x
-= child
->m_x
;
1254 event
.m_y
-= child
->m_y
;
1261 event
.SetEventObject( win
);
1263 if (win
->GetEventHandler()->ProcessEvent( event
))
1265 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1272 //-----------------------------------------------------------------------------
1274 //-----------------------------------------------------------------------------
1276 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1279 wxapp_install_idle_handler();
1281 if (!win
->m_hasVMT
) return FALSE
;
1282 if (g_blockEventsOnDrag
) return FALSE
;
1284 switch ( g_sendActivateEvent
)
1287 // we've got focus from outside, synthtize wxActivateEvent
1288 g_sendActivateEvent
= 1;
1292 // another our window just lost focus, it was already ours before
1293 // - don't send any wxActivateEvent
1294 g_sendActivateEvent
= -1;
1298 g_focusWindow
= win
;
1301 printf( "OnSetFocus from " );
1302 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1303 printf( win->GetClassInfo()->GetClassName() );
1305 printf( WXSTRINGCAST win->GetLabel() );
1309 wxPanel
*panel
= wxDynamicCast(win
->GetParent(), wxPanel
);
1312 panel
->SetLastFocus(win
);
1317 gdk_im_begin(win
->m_ic
, win
->m_wxwindow
->window
);
1320 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1321 event
.SetEventObject( win
);
1323 if (win
->GetEventHandler()->ProcessEvent( event
))
1325 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1332 //-----------------------------------------------------------------------------
1333 // "focus_out_event"
1334 //-----------------------------------------------------------------------------
1336 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1339 wxapp_install_idle_handler();
1341 if (!win
->m_hasVMT
) return FALSE
;
1342 if (g_blockEventsOnDrag
) return FALSE
;
1344 // if the focus goes out of our app alltogether, OnIdle() will send
1345 // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset
1346 // g_sendActivateEvent to -1
1347 g_sendActivateEvent
= 0;
1349 g_focusWindow
= (wxWindow
*)NULL
;
1352 printf( "OnKillFocus from " );
1353 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1354 printf( win->GetClassInfo()->GetClassName() );
1363 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1364 event
.SetEventObject( win
);
1366 if (win
->GetEventHandler()->ProcessEvent( event
))
1368 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1375 //-----------------------------------------------------------------------------
1376 // "enter_notify_event"
1377 //-----------------------------------------------------------------------------
1379 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1382 wxapp_install_idle_handler();
1384 if (!win
->m_hasVMT
) return FALSE
;
1385 if (g_blockEventsOnDrag
) return FALSE
;
1387 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1389 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1390 #if (GTK_MINOR_VERSION > 0)
1391 event
.SetTimestamp( gdk_event
->time
);
1393 event
.SetEventObject( win
);
1397 GdkModifierType state
= (GdkModifierType
)0;
1399 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1401 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1402 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1403 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1404 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1405 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1406 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1407 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1412 if (win
->GetEventHandler()->ProcessEvent( event
))
1414 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1421 //-----------------------------------------------------------------------------
1422 // "leave_notify_event"
1423 //-----------------------------------------------------------------------------
1425 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1428 wxapp_install_idle_handler();
1430 if (!win
->m_hasVMT
) return FALSE
;
1431 if (g_blockEventsOnDrag
) return FALSE
;
1433 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1435 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1436 #if (GTK_MINOR_VERSION > 0)
1437 event
.SetTimestamp( gdk_event
->time
);
1439 event
.SetEventObject( win
);
1443 GdkModifierType state
= (GdkModifierType
)0;
1445 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1447 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1448 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1449 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1450 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1451 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1452 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1453 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1458 if (win
->GetEventHandler()->ProcessEvent( event
))
1460 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1467 //-----------------------------------------------------------------------------
1468 // "value_changed" from m_vAdjust
1469 //-----------------------------------------------------------------------------
1471 static void gtk_window_vscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1474 wxapp_install_idle_handler();
1476 if (g_blockEventsOnDrag
) return;
1478 if (!win
->m_hasVMT
) return;
1480 float diff
= adjust
->value
- win
->m_oldVerticalPos
;
1481 if (fabs(diff
) < 0.2) return;
1483 win
->m_oldVerticalPos
= adjust
->value
;
1485 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1486 GtkRange
*range
= GTK_RANGE( scrolledWindow
->vscrollbar
);
1488 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1489 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1490 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1491 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1492 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1494 int value
= (int)(adjust
->value
+0.5);
1496 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1497 event
.SetEventObject( win
);
1498 win
->GetEventHandler()->ProcessEvent( event
);
1501 //-----------------------------------------------------------------------------
1502 // "value_changed" from m_hAdjust
1503 //-----------------------------------------------------------------------------
1505 static void gtk_window_hscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1508 wxapp_install_idle_handler();
1510 if (g_blockEventsOnDrag
) return;
1511 if (!win
->m_hasVMT
) return;
1513 float diff
= adjust
->value
- win
->m_oldHorizontalPos
;
1514 if (fabs(diff
) < 0.2) return;
1516 win
->m_oldHorizontalPos
= adjust
->value
;
1518 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1519 GtkRange
*range
= GTK_RANGE( scrolledWindow
->hscrollbar
);
1521 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1522 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1523 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1524 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1525 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1527 int value
= (int)(adjust
->value
+0.5);
1529 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1530 event
.SetEventObject( win
);
1531 win
->GetEventHandler()->ProcessEvent( event
);
1534 //-----------------------------------------------------------------------------
1535 // "changed" from m_vAdjust
1536 //-----------------------------------------------------------------------------
1538 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1541 wxapp_install_idle_handler();
1543 if (g_blockEventsOnDrag
) return;
1544 if (!win
->m_hasVMT
) return;
1546 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1547 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1549 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1550 event
.SetEventObject( win
);
1551 win
->GetEventHandler()->ProcessEvent( event
);
1554 //-----------------------------------------------------------------------------
1555 // "changed" from m_hAdjust
1556 //-----------------------------------------------------------------------------
1558 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1561 wxapp_install_idle_handler();
1563 if (g_blockEventsOnDrag
) return;
1564 if (!win
->m_hasVMT
) return;
1566 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1567 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1569 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1570 event
.SetEventObject( win
);
1571 win
->GetEventHandler()->ProcessEvent( event
);
1574 //-----------------------------------------------------------------------------
1575 // "button_press_event" from scrollbar
1576 //-----------------------------------------------------------------------------
1578 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1579 GdkEventButton
*WXUNUSED(gdk_event
),
1583 wxapp_install_idle_handler();
1585 // don't test here as we can release the mouse while being over
1586 // a different window than the slider
1588 // if (gdk_event->window != widget->slider) return FALSE;
1590 win
->SetScrolling( TRUE
);
1595 //-----------------------------------------------------------------------------
1596 // "button_release_event" from scrollbar
1597 //-----------------------------------------------------------------------------
1599 static gint
gtk_scrollbar_button_release_callback( GtkRange
*WXUNUSED(widget
),
1600 GdkEventButton
*WXUNUSED(gdk_event
),
1604 // don't test here as we can release the mouse while being over
1605 // a different window than the slider
1607 // if (gdk_event->window != widget->slider) return FALSE;
1609 win
->SetScrolling( FALSE
);
1614 // ----------------------------------------------------------------------------
1615 // this wxWindowBase function is implemented here (in platform-specific file)
1616 // because it is static and so couldn't be made virtual
1617 // ----------------------------------------------------------------------------
1619 wxWindow
*wxWindowBase::FindFocus()
1621 return g_focusWindow
;
1624 //-----------------------------------------------------------------------------
1625 // "realize" from m_widget
1626 //-----------------------------------------------------------------------------
1628 /* We cannot set colours and fonts before the widget has
1629 been realized, so we do this directly after realization. */
1632 gtk_window_realized_callback( GtkWidget
*WXUNUSED(m_widget
), wxWindow
*win
)
1635 wxapp_install_idle_handler();
1637 if (win
->m_delayedBackgroundColour
)
1638 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1640 if (win
->m_delayedForegroundColour
)
1641 win
->SetForegroundColour( win
->GetForegroundColour() );
1643 wxWindowCreateEvent
event( win
);
1644 event
.SetEventObject( win
);
1645 win
->GetEventHandler()->ProcessEvent( event
);
1650 //-----------------------------------------------------------------------------
1652 //-----------------------------------------------------------------------------
1655 #define WXUNUSED_UNLESS_XIM(param) param
1657 #define WXUNUSED_UNLESS_XIM(param) WXUNUSED(param)
1660 /* Resize XIM window */
1663 void gtk_wxwindow_size_callback( GtkWidget
* WXUNUSED_UNLESS_XIM(widget
),
1664 GtkAllocation
* WXUNUSED_UNLESS_XIM(alloc
),
1665 wxFrame
* WXUNUSED_UNLESS_XIM(win
) )
1668 wxapp_install_idle_handler();
1674 if (gdk_ic_get_style (win
->m_ic
) & GDK_IM_PREEDIT_POSITION
)
1678 gdk_window_get_size (widget
->window
, &width
, &height
);
1679 win
->m_icattr
->preedit_area
.width
= width
;
1680 win
->m_icattr
->preedit_area
.height
= height
;
1681 gdk_ic_set_attr (win
->m_ic
, win
->m_icattr
, GDK_IC_PREEDIT_AREA
);
1686 //-----------------------------------------------------------------------------
1687 // "realize" from m_wxwindow
1688 //-----------------------------------------------------------------------------
1690 /* Initialize XIM support */
1693 gtk_wxwindow_realized_callback( GtkWidget
* WXUNUSED_UNLESS_XIM(widget
),
1694 wxWindow
* WXUNUSED_UNLESS_XIM(win
) )
1697 wxapp_install_idle_handler();
1700 if (win
->m_ic
) return FALSE
;
1701 if (!widget
) return FALSE
;
1702 if (!gdk_im_ready()) return FALSE
;
1704 win
->m_icattr
= gdk_ic_attr_new();
1705 if (!win
->m_icattr
) return FALSE
;
1709 GdkColormap
*colormap
;
1710 GdkICAttr
*attr
= win
->m_icattr
;
1711 unsigned attrmask
= GDK_IC_ALL_REQ
;
1713 GdkIMStyle supported_style
= (GdkIMStyle
)
1714 (GDK_IM_PREEDIT_NONE
|
1715 GDK_IM_PREEDIT_NOTHING
|
1716 GDK_IM_PREEDIT_POSITION
|
1717 GDK_IM_STATUS_NONE
|
1718 GDK_IM_STATUS_NOTHING
);
1720 if (widget
->style
&& widget
->style
->font
->type
!= GDK_FONT_FONTSET
)
1721 supported_style
= (GdkIMStyle
)(supported_style
& ~GDK_IM_PREEDIT_POSITION
);
1723 attr
->style
= style
= gdk_im_decide_style (supported_style
);
1724 attr
->client_window
= widget
->window
;
1726 if ((colormap
= gtk_widget_get_colormap (widget
)) !=
1727 gtk_widget_get_default_colormap ())
1729 attrmask
|= GDK_IC_PREEDIT_COLORMAP
;
1730 attr
->preedit_colormap
= colormap
;
1733 attrmask
|= GDK_IC_PREEDIT_FOREGROUND
;
1734 attrmask
|= GDK_IC_PREEDIT_BACKGROUND
;
1735 attr
->preedit_foreground
= widget
->style
->fg
[GTK_STATE_NORMAL
];
1736 attr
->preedit_background
= widget
->style
->base
[GTK_STATE_NORMAL
];
1738 switch (style
& GDK_IM_PREEDIT_MASK
)
1740 case GDK_IM_PREEDIT_POSITION
:
1741 if (widget
->style
&& widget
->style
->font
->type
!= GDK_FONT_FONTSET
)
1743 g_warning ("over-the-spot style requires fontset");
1747 gdk_window_get_size (widget
->window
, &width
, &height
);
1749 attrmask
|= GDK_IC_PREEDIT_POSITION_REQ
;
1750 attr
->spot_location
.x
= 0;
1751 attr
->spot_location
.y
= height
;
1752 attr
->preedit_area
.x
= 0;
1753 attr
->preedit_area
.y
= 0;
1754 attr
->preedit_area
.width
= width
;
1755 attr
->preedit_area
.height
= height
;
1756 attr
->preedit_fontset
= widget
->style
->font
;
1761 win
->m_ic
= gdk_ic_new (attr
, (GdkICAttributesType
)attrmask
);
1763 if (win
->m_ic
== NULL
)
1764 g_warning ("Can't create input context.");
1767 mask
= gdk_window_get_events (widget
->window
);
1768 mask
= (GdkEventMask
)(mask
| gdk_ic_get_events (win
->m_ic
));
1769 gdk_window_set_events (widget
->window
, mask
);
1771 if (GTK_WIDGET_HAS_FOCUS(widget
))
1772 gdk_im_begin (win
->m_ic
, widget
->window
);
1779 //-----------------------------------------------------------------------------
1780 // InsertChild for wxWindow.
1781 //-----------------------------------------------------------------------------
1783 /* Callback for wxWindow. This very strange beast has to be used because
1784 * C++ has no virtual methods in a constructor. We have to emulate a
1785 * virtual function here as wxNotebook requires a different way to insert
1786 * a child in it. I had opted for creating a wxNotebookPage window class
1787 * which would have made this superfluous (such in the MDI window system),
1788 * but no-one was listening to me... */
1790 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1792 /* the window might have been scrolled already, do we
1793 have to adapt the position */
1794 GtkPizza
*pizza
= GTK_PIZZA(parent
->m_wxwindow
);
1795 child
->m_x
+= pizza
->xoffset
;
1796 child
->m_y
+= pizza
->yoffset
;
1798 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
1799 GTK_WIDGET(child
->m_widget
),
1806 //-----------------------------------------------------------------------------
1808 //-----------------------------------------------------------------------------
1810 wxWindow
* wxGetActiveWindow()
1812 return g_focusWindow
;
1815 //-----------------------------------------------------------------------------
1817 //-----------------------------------------------------------------------------
1819 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1821 void wxWindow::Init()
1827 m_widget
= (GtkWidget
*) NULL
;
1828 m_wxwindow
= (GtkWidget
*) NULL
;
1838 m_needParent
= TRUE
;
1839 m_isBeingDeleted
= FALSE
;
1842 m_nativeSizeEvent
= FALSE
;
1844 m_hasScrolling
= FALSE
;
1845 m_isScrolling
= FALSE
;
1847 m_hAdjust
= (GtkAdjustment
*) NULL
;
1848 m_vAdjust
= (GtkAdjustment
*) NULL
;
1849 m_oldHorizontalPos
= 0.0;
1850 m_oldVerticalPos
= 0.0;
1853 m_widgetStyle
= (GtkStyle
*) NULL
;
1855 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1857 m_isStaticBox
= FALSE
;
1858 m_isRadioButton
= FALSE
;
1860 m_acceptsFocus
= FALSE
;
1862 m_cursor
= *wxSTANDARD_CURSOR
;
1865 m_ic
= (GdkIC
*) NULL
;
1866 m_icattr
= (GdkICAttr
*) NULL
;
1870 wxWindow::wxWindow()
1875 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1876 const wxPoint
&pos
, const wxSize
&size
,
1877 long style
, const wxString
&name
)
1881 Create( parent
, id
, pos
, size
, style
, name
);
1884 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1885 const wxPoint
&pos
, const wxSize
&size
,
1886 long style
, const wxString
&name
)
1888 if (!PreCreation( parent
, pos
, size
) ||
1889 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
1891 wxFAIL_MSG( wxT("wxWindow creation failed") );
1895 m_insertCallback
= wxInsertChildInWindow
;
1897 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1898 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1901 debug_focus_in( m_widget
, wxT("wxWindow::m_widget"), name
);
1904 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1907 debug_focus_in( scrolledWindow
->hscrollbar
, wxT("wxWindow::hsrcollbar"), name
);
1908 debug_focus_in( scrolledWindow
->vscrollbar
, wxT("wxWindow::vsrcollbar"), name
);
1911 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1912 scroll_class
->scrollbar_spacing
= 0;
1914 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1916 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1917 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1919 m_wxwindow
= gtk_pizza_new();
1922 debug_focus_in( m_wxwindow
, wxT("wxWindow::m_wxwindow"), name
);
1925 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1927 #if (GTK_MINOR_VERSION > 0)
1928 GtkPizza
*pizza
= GTK_PIZZA(m_wxwindow
);
1930 if (HasFlag(wxRAISED_BORDER
))
1932 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_OUT
);
1934 else if (HasFlag(wxSUNKEN_BORDER
))
1936 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_IN
);
1938 else if (HasFlag(wxSIMPLE_BORDER
))
1940 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_THIN
);
1944 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_NONE
);
1946 #else // GTK_MINOR_VERSION == 0
1947 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1949 if (HasFlag(wxRAISED_BORDER
))
1951 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1953 else if (HasFlag(wxSUNKEN_BORDER
))
1955 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1959 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1961 #endif // GTK_MINOR_VERSION
1963 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1964 m_acceptsFocus
= TRUE
;
1966 #if (GTK_MINOR_VERSION == 0)
1967 // shut the viewport up
1968 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1969 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1970 #endif // GTK_MINOR_VERSION == 0
1972 // I _really_ don't want scrollbars in the beginning
1973 m_vAdjust
->lower
= 0.0;
1974 m_vAdjust
->upper
= 1.0;
1975 m_vAdjust
->value
= 0.0;
1976 m_vAdjust
->step_increment
= 1.0;
1977 m_vAdjust
->page_increment
= 1.0;
1978 m_vAdjust
->page_size
= 5.0;
1979 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1980 m_hAdjust
->lower
= 0.0;
1981 m_hAdjust
->upper
= 1.0;
1982 m_hAdjust
->value
= 0.0;
1983 m_hAdjust
->step_increment
= 1.0;
1984 m_hAdjust
->page_increment
= 1.0;
1985 m_hAdjust
->page_size
= 5.0;
1986 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1988 // these handlers block mouse events to any window during scrolling such as
1989 // motion events and prevent GTK and wxWindows from fighting over where the
1992 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1993 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1995 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1996 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1998 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1999 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
2001 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
2002 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
2004 // these handlers get notified when screen updates are required either when
2005 // scrolling or when the window size (and therefore scrollbar configuration)
2008 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
2009 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
2010 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
2011 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
2013 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
2014 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
2015 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
2016 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
2018 gtk_widget_show( m_wxwindow
);
2021 m_parent
->DoAddChild( this );
2030 wxWindow::~wxWindow()
2032 m_isBeingDeleted
= TRUE
;
2041 m_parent
->RemoveChild( this );
2045 gdk_ic_destroy (m_ic
);
2047 gdk_ic_attr_destroy (m_icattr
);
2052 gtk_style_unref( m_widgetStyle
);
2053 m_widgetStyle
= (GtkStyle
*) NULL
;
2058 gtk_widget_destroy( m_wxwindow
);
2059 m_wxwindow
= (GtkWidget
*) NULL
;
2064 gtk_widget_destroy( m_widget
);
2065 m_widget
= (GtkWidget
*) NULL
;
2069 bool wxWindow::PreCreation( wxWindow
*parent
, const wxPoint
&pos
, const wxSize
&size
)
2071 wxCHECK_MSG( !m_needParent
|| parent
, FALSE
, wxT("Need complete parent.") );
2073 /* this turns -1 into 20 so that a minimal window is
2074 visible even although -1,-1 has been given as the
2075 size of the window. the same trick is used in other
2076 ports and should make debugging easier */
2077 m_width
= WidthDefault(size
.x
);
2078 m_height
= HeightDefault(size
.y
);
2083 /* some reasonable defaults */
2088 m_x
= (gdk_screen_width () - m_width
) / 2;
2089 if (m_x
< 10) m_x
= 10;
2093 m_y
= (gdk_screen_height () - m_height
) / 2;
2094 if (m_y
< 10) m_y
= 10;
2101 void wxWindow::PostCreation()
2103 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2109 /* these get reported to wxWindows -> wxPaintEvent */
2110 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
2111 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
2113 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
2114 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
2117 #if (GTK_MINOR_VERSION > 0)
2118 /* these are called when the "sunken" or "raised" borders are drawn */
2119 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
2120 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
2122 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
2123 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
2127 if (m_wxwindow
&& m_needParent
)
2129 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "focus_in_event",
2130 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2132 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "focus_out_event",
2133 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2137 // For dialogs and frames, we are interested mainly in
2138 // m_widget's focus.
2140 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_in_event",
2141 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2143 gtk_signal_connect( GTK_OBJECT(m_widget
), "focus_out_event",
2144 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2147 GtkWidget
*connect_widget
= GetConnectWidget();
2149 ConnectWidget( connect_widget
);
2151 /* We cannot set colours, fonts and cursors before the widget has
2152 been realized, so we do this directly after realization */
2153 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
2154 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
2158 /* Initialize XIM support. */
2159 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "realize",
2160 GTK_SIGNAL_FUNC(gtk_wxwindow_realized_callback
), (gpointer
) this );
2162 /* And resize XIM window. */
2163 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "size_allocate",
2164 GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback
), (gpointer
)this );
2170 void wxWindow::ConnectWidget( GtkWidget
*widget
)
2172 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
2173 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
2175 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
2176 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
2178 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
2179 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
2181 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
2182 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
2184 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
2185 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
2187 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
2188 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
2190 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
2191 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
2194 bool wxWindow::Destroy()
2196 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2200 return wxWindowBase::Destroy();
2203 void wxWindow::DoMoveWindow(int x
, int y
, int width
, int height
)
2205 gtk_pizza_set_size( GTK_PIZZA(m_parent
->m_wxwindow
), m_widget
, x
, y
, width
, height
);
2208 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
2210 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2211 wxASSERT_MSG( (m_parent
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") );
2213 if (m_resizing
) return; /* I don't like recursions */
2216 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
2218 /* don't set the size for children of wxNotebook, just take the values. */
2226 GtkPizza
*pizza
= GTK_PIZZA(m_parent
->m_wxwindow
);
2228 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
2230 if (x
!= -1) m_x
= x
+ pizza
->xoffset
;
2231 if (y
!= -1) m_y
= y
+ pizza
->yoffset
;
2232 if (width
!= -1) m_width
= width
;
2233 if (height
!= -1) m_height
= height
;
2237 m_x
= x
+ pizza
->xoffset
;
2238 m_y
= y
+ pizza
->yoffset
;
2243 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2245 if (width
== -1) m_width
= 80;
2248 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2250 if (height
== -1) m_height
= 26;
2253 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2254 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2255 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2256 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2259 int bottom_border
= 0;
2261 if (GTK_WIDGET_CAN_DEFAULT(m_widget
))
2263 /* the default button has a border around it */
2268 DoMoveWindow( m_x
-border
,
2271 m_height
+border
+bottom_border
);
2275 wxPrintf( "OnSize sent from " );
2276 if (GetClassInfo() && GetClassInfo()->GetClassName())
2277 wxPrintf( GetClassInfo()->GetClassName() );
2278 wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height );
2281 if (!m_nativeSizeEvent
)
2283 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2284 event
.SetEventObject( this );
2285 GetEventHandler()->ProcessEvent( event
);
2291 void wxWindow::OnInternalIdle()
2293 if ( g_sendActivateEvent
!= -1 )
2295 bool activate
= g_sendActivateEvent
!= 0;
2298 g_sendActivateEvent
= -1;
2300 wxActivateEvent
event(wxEVT_ACTIVATE
, activate
, GetId());
2301 event
.SetEventObject(this);
2303 (void)GetEventHandler()->ProcessEvent(event
);
2306 wxCursor cursor
= m_cursor
;
2307 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2311 /* I now set the cursor anew in every OnInternalIdle call
2312 as setting the cursor in a parent window also effects the
2313 windows above so that checking for the current cursor is
2318 GdkWindow
*window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2320 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2322 if (!g_globalCursor
.Ok())
2323 cursor
= *wxSTANDARD_CURSOR
;
2325 window
= m_widget
->window
;
2326 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2327 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2333 GdkWindow
*window
= m_widget
->window
;
2334 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2335 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2343 void wxWindow::DoGetSize( int *width
, int *height
) const
2345 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2347 if (width
) (*width
) = m_width
;
2348 if (height
) (*height
) = m_height
;
2351 void wxWindow::DoSetClientSize( int width
, int height
)
2353 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2357 SetSize( width
, height
);
2364 #if (GTK_MINOR_VERSION == 0)
2365 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2369 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2370 #if 0 // unused - if this is ok, just remove this line (VZ)
2371 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2374 GtkWidget
*viewport
= scroll_window
->viewport
;
2375 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2377 dw
+= 2 * viewport_class
->xthickness
;
2378 dh
+= 2 * viewport_class
->ythickness
;
2382 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2384 /* when using GTK 1.2 we set the shadow border size to 2 */
2388 if (HasFlag(wxSIMPLE_BORDER
))
2390 /* when using GTK 1.2 we set the simple border size to 1 */
2399 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2400 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2402 we use this instead: range.slider_width = 11 + 2*2pts edge
2405 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2406 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2408 if (scroll_window
->vscrollbar_visible
)
2410 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2411 dw
+= scroll_class
->scrollbar_spacing
;
2414 if (scroll_window
->hscrollbar_visible
)
2416 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2417 dh
+= scroll_class
->scrollbar_spacing
;
2421 SetSize( width
+dw
, height
+dh
);
2425 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2427 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2431 if (width
) (*width
) = m_width
;
2432 if (height
) (*height
) = m_height
;
2439 #if (GTK_MINOR_VERSION == 0)
2440 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2444 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2445 #if 0 // unused - if this is ok, just remove this line (VZ)
2446 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2449 GtkWidget
*viewport
= scroll_window
->viewport
;
2450 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2452 dw
+= 2 * viewport_class
->xthickness
;
2453 dh
+= 2 * viewport_class
->ythickness
;
2457 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2459 /* when using GTK 1.2 we set the shadow border size to 2 */
2463 if (HasFlag(wxSIMPLE_BORDER
))
2465 /* when using GTK 1.2 we set the simple border size to 1 */
2473 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2474 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2476 we use this instead: range.slider_width = 11 + 2*2pts edge
2479 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2480 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2482 if (scroll_window
->vscrollbar_visible
)
2484 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2485 dw
+= scroll_class
->scrollbar_spacing
;
2488 if (scroll_window
->hscrollbar_visible
)
2490 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2491 dh
+= scroll_class
->scrollbar_spacing
;
2495 if (width
) (*width
) = m_width
- dw
;
2496 if (height
) (*height
) = m_height
- dh
;
2500 void wxWindow::DoGetPosition( int *x
, int *y
) const
2502 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2506 if (m_parent
&& m_parent
->m_wxwindow
)
2508 GtkPizza
*pizza
= GTK_PIZZA(m_parent
->m_wxwindow
);
2509 dx
= pizza
->xoffset
;
2510 dy
= pizza
->yoffset
;
2513 if (x
) (*x
) = m_x
- dx
;
2514 if (y
) (*y
) = m_y
- dy
;
2517 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2519 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2521 if (!m_widget
->window
) return;
2523 GdkWindow
*source
= (GdkWindow
*) NULL
;
2525 source
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2527 source
= m_widget
->window
;
2531 gdk_window_get_origin( source
, &org_x
, &org_y
);
2535 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2537 org_x
+= m_widget
->allocation
.x
;
2538 org_y
+= m_widget
->allocation
.y
;
2546 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2548 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2550 if (!m_widget
->window
) return;
2552 GdkWindow
*source
= (GdkWindow
*) NULL
;
2554 source
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2556 source
= m_widget
->window
;
2560 gdk_window_get_origin( source
, &org_x
, &org_y
);
2564 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2566 org_x
+= m_widget
->allocation
.x
;
2567 org_y
+= m_widget
->allocation
.y
;
2575 bool wxWindow::Show( bool show
)
2577 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2579 if (!wxWindowBase::Show(show
))
2586 gtk_widget_show( m_widget
);
2588 gtk_widget_hide( m_widget
);
2593 bool wxWindow::Enable( bool enable
)
2595 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2597 if (!wxWindowBase::Enable(enable
))
2603 gtk_widget_set_sensitive( m_widget
, enable
);
2605 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2610 int wxWindow::GetCharHeight() const
2612 wxCHECK_MSG( (m_widget
!= NULL
), 12, wxT("invalid window") );
2614 wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") );
2616 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2618 return font
->ascent
+ font
->descent
;
2621 int wxWindow::GetCharWidth() const
2623 wxCHECK_MSG( (m_widget
!= NULL
), 8, wxT("invalid window") );
2625 wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") );
2627 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2629 return gdk_string_width( font
, "H" );
2632 void wxWindow::GetTextExtent( const wxString
& string
,
2636 int *externalLeading
,
2637 const wxFont
*theFont
) const
2639 wxFont fontToUse
= m_font
;
2640 if (theFont
) fontToUse
= *theFont
;
2642 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
2644 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2645 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2646 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2647 if (descent
) (*descent
) = font
->descent
;
2648 if (externalLeading
) (*externalLeading
) = 0; // ??
2651 void wxWindow::SetFocus()
2653 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2657 if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow
))
2658 gtk_widget_grab_focus (m_wxwindow
);
2664 if (GTK_WIDGET_CAN_FOCUS(m_widget
) && !GTK_WIDGET_HAS_FOCUS (m_widget
) )
2666 gtk_widget_grab_focus (m_widget
);
2668 else if (GTK_IS_CONTAINER(m_widget
))
2670 gtk_container_focus( GTK_CONTAINER(m_widget
), GTK_DIR_TAB_FORWARD
);
2679 bool wxWindow::AcceptsFocus() const
2681 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2684 bool wxWindow::Reparent( wxWindowBase
*newParentBase
)
2686 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2688 wxWindow
*oldParent
= m_parent
,
2689 *newParent
= (wxWindow
*)newParentBase
;
2691 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2693 if ( !wxWindowBase::Reparent(newParent
) )
2696 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2698 /* prevent GTK from deleting the widget arbitrarily */
2699 gtk_widget_ref( m_widget
);
2703 gtk_container_remove( GTK_CONTAINER(m_widget
->parent
), m_widget
);
2706 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2710 /* insert GTK representation */
2711 (*(newParent
->m_insertCallback
))(newParent
, this);
2714 /* reverse: prevent GTK from deleting the widget arbitrarily */
2715 gtk_widget_unref( m_widget
);
2720 void wxWindow::DoAddChild(wxWindow
*child
)
2722 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2724 wxASSERT_MSG( (child
!= NULL
), wxT("invalid child window") );
2726 wxASSERT_MSG( (m_insertCallback
!= NULL
), wxT("invalid child insertion function") );
2731 /* insert GTK representation */
2732 (*m_insertCallback
)(this, child
);
2735 void wxWindow::Raise()
2737 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2739 if (!m_widget
->window
) return;
2741 gdk_window_raise( m_widget
->window
);
2744 void wxWindow::Lower()
2746 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2748 if (!m_widget
->window
) return;
2750 gdk_window_lower( m_widget
->window
);
2753 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2755 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2757 return wxWindowBase::SetCursor( cursor
);
2760 void wxWindow::WarpPointer( int x
, int y
)
2762 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2764 /* we provide this function ourselves as it is
2765 missing in GDK (top of this file) */
2767 GdkWindow
*window
= (GdkWindow
*) NULL
;
2769 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2771 window
= GetConnectWidget()->window
;
2774 gdk_window_warp_pointer( window
, x
, y
);
2777 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2779 if (!m_widget
) return;
2780 if (!m_widget
->window
) return;
2782 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2786 gdk_window_clear_area( GTK_PIZZA(m_wxwindow
)->bin_window
,
2788 rect
->width
, rect
->height
);
2792 gdk_window_clear( GTK_PIZZA(m_wxwindow
)->bin_window
);
2796 /* there is no GTK equivalent of "draw only, don't clear" so we
2797 invent our own in the GtkPizza widget */
2803 GtkPizza
*pizza
= GTK_PIZZA(m_wxwindow
);
2804 gboolean old_clear
= pizza
->clear_on_draw
;
2805 gtk_pizza_set_clear( pizza
, FALSE
);
2807 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2809 gtk_pizza_set_clear( pizza
, old_clear
);
2812 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2816 GdkRectangle gdk_rect
;
2817 gdk_rect
.x
= rect
->x
;
2818 gdk_rect
.y
= rect
->y
;
2819 gdk_rect
.width
= rect
->width
;
2820 gdk_rect
.height
= rect
->height
;
2824 GtkPizza
*pizza
= GTK_PIZZA(m_wxwindow
);
2825 gboolean old_clear
= pizza
->clear_on_draw
;
2826 gtk_pizza_set_clear( pizza
, FALSE
);
2828 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2830 gtk_pizza_set_clear( pizza
, old_clear
);
2833 gtk_widget_draw( m_widget
, &gdk_rect
);
2837 void wxWindow::Clear()
2839 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2841 if (!m_widget
->window
) return;
2843 if (m_wxwindow
&& m_wxwindow
->window
)
2845 gdk_window_clear( m_wxwindow
->window
);
2850 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2852 wxWindowBase::DoSetToolTip(tip
);
2855 m_tooltip
->Apply( this );
2858 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2860 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2862 #endif // wxUSE_TOOLTIPS
2864 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2866 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2868 if (!wxWindowBase::SetBackgroundColour(colour
))
2870 // don't leave if the GTK widget has just
2872 if (!m_delayedBackgroundColour
) return FALSE
;
2875 GdkWindow
*window
= (GdkWindow
*) NULL
;
2877 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2879 window
= GetConnectWidget()->window
;
2883 // indicate that a new style has been set
2884 // but it couldn't get applied as the
2885 // widget hasn't been realized yet.
2886 m_delayedBackgroundColour
= TRUE
;
2888 // pretend we have done something
2893 (m_backgroundColour
!= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE
)))
2895 /* wxMSW doesn't clear the window here. I don't do that either to
2896 provide compatibility. call Clear() to do the job. */
2898 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2899 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2907 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2909 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2911 if (!wxWindowBase::SetForegroundColour(colour
))
2913 // don't leave if the GTK widget has just
2915 if (!m_delayedForegroundColour
) return FALSE
;
2918 GdkWindow
*window
= (GdkWindow
*) NULL
;
2920 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2922 window
= GetConnectWidget()->window
;
2926 // indicate that a new style has been set
2927 // but it couldn't get applied as the
2928 // widget hasn't been realized yet.
2929 m_delayedForegroundColour
= TRUE
;
2931 // pretend we have done something
2940 GtkStyle
*wxWindow::GetWidgetStyle()
2942 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2944 GtkStyle
*def
= gtk_rc_get_style( m_widget
);
2947 def
= gtk_widget_get_default_style();
2949 m_widgetStyle
= gtk_style_copy( def
);
2950 m_widgetStyle
->engine_data
= def
->engine_data
;
2951 m_widgetStyle
->klass
= def
->klass
;
2953 return m_widgetStyle
;
2956 void wxWindow::SetWidgetStyle()
2958 GtkStyle
*style
= GetWidgetStyle();
2960 if (m_font
!= wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT
))
2962 gdk_font_unref( style
->font
);
2963 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2966 if (m_foregroundColour
.Ok())
2968 m_foregroundColour
.CalcPixel( gtk_widget_get_colormap( m_widget
) );
2969 if (m_foregroundColour
!= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT
))
2971 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2972 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2973 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2977 if (m_backgroundColour
.Ok())
2979 m_backgroundColour
.CalcPixel( gtk_widget_get_colormap( m_widget
) );
2980 if (m_backgroundColour
!= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE
))
2982 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2983 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2984 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2985 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2986 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2987 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2988 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2989 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2994 void wxWindow::ApplyWidgetStyle()
2998 //-----------------------------------------------------------------------------
2999 // Pop-up menu stuff
3000 //-----------------------------------------------------------------------------
3002 static void gtk_pop_hide_callback( GtkWidget
*WXUNUSED(widget
), bool* is_waiting
)
3004 *is_waiting
= FALSE
;
3007 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
3009 menu
->SetInvokingWindow( win
);
3010 wxMenuItemList::Node
*node
= menu
->GetMenuItems().GetFirst();
3013 wxMenuItem
*menuitem
= node
->GetData();
3014 if (menuitem
->IsSubMenu())
3016 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
3019 node
= node
->GetNext();
3023 static gint gs_pop_x
= 0;
3024 static gint gs_pop_y
= 0;
3026 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
3030 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
3035 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
3037 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
3039 wxCHECK_MSG( menu
!= NULL
, FALSE
, wxT("invalid popup-menu") );
3041 SetInvokingWindow( menu
, this );
3048 bool is_waiting
= TRUE
;
3050 gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide",
3051 GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting
);
3054 GTK_MENU(menu
->m_menu
),
3055 (GtkWidget
*) NULL
, // parent menu shell
3056 (GtkWidget
*) NULL
, // parent menu item
3057 (GtkMenuPositionFunc
) pop_pos_callback
,
3058 (gpointer
) this, // client data
3059 0, // button used to activate it
3060 gs_timeLastClick
// the time of activation
3065 while (gtk_events_pending())
3066 gtk_main_iteration();
3072 #if wxUSE_DRAG_AND_DROP
3074 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
3076 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3078 GtkWidget
*dnd_widget
= GetConnectWidget();
3080 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
3082 if (m_dropTarget
) delete m_dropTarget
;
3083 m_dropTarget
= dropTarget
;
3085 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
3088 #endif // wxUSE_DRAG_AND_DROP
3090 GtkWidget
* wxWindow::GetConnectWidget()
3092 GtkWidget
*connect_widget
= m_widget
;
3093 if (m_wxwindow
) connect_widget
= m_wxwindow
;
3095 return connect_widget
;
3098 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
3101 return (window
== GTK_PIZZA(m_wxwindow
)->bin_window
);
3103 return (window
== m_widget
->window
);
3106 bool wxWindow::SetFont( const wxFont
&font
)
3108 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
3110 if (!wxWindowBase::SetFont(font
))
3115 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
3116 if ( sysbg
== m_backgroundColour
)
3118 m_backgroundColour
= wxNullColour
;
3120 m_backgroundColour
= sysbg
;
3130 void wxWindow::CaptureMouse()
3132 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3134 wxCHECK_RET( g_captureWindow
== NULL
, wxT("CaptureMouse called twice") );
3136 GdkWindow
*window
= (GdkWindow
*) NULL
;
3138 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
3140 window
= GetConnectWidget()->window
;
3142 if (!window
) return;
3144 gdk_pointer_grab( window
, FALSE
,
3146 (GDK_BUTTON_PRESS_MASK
|
3147 GDK_BUTTON_RELEASE_MASK
|
3148 GDK_POINTER_MOTION_HINT_MASK
|
3149 GDK_POINTER_MOTION_MASK
),
3151 m_cursor
.GetCursor(),
3152 (guint32
)GDK_CURRENT_TIME
);
3153 g_captureWindow
= this;
3156 void wxWindow::ReleaseMouse()
3158 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3160 wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") );
3162 GdkWindow
*window
= (GdkWindow
*) NULL
;
3164 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
3166 window
= GetConnectWidget()->window
;
3171 gdk_pointer_ungrab ( (guint32
)GDK_CURRENT_TIME
);
3172 g_captureWindow
= (wxWindow
*) NULL
;
3175 bool wxWindow::IsRetained() const
3180 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3181 int range
, bool refresh
)
3183 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3185 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3187 m_hasScrolling
= TRUE
;
3189 if (orient
== wxHORIZONTAL
)
3191 float fpos
= (float)pos
;
3192 float frange
= (float)range
;
3193 float fthumb
= (float)thumbVisible
;
3194 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3195 if (fpos
< 0.0) fpos
= 0.0;
3197 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3198 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3200 SetScrollPos( orient
, pos
, refresh
);
3204 m_oldHorizontalPos
= fpos
;
3206 m_hAdjust
->lower
= 0.0;
3207 m_hAdjust
->upper
= frange
;
3208 m_hAdjust
->value
= fpos
;
3209 m_hAdjust
->step_increment
= 1.0;
3210 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3211 m_hAdjust
->page_size
= fthumb
;
3215 float fpos
= (float)pos
;
3216 float frange
= (float)range
;
3217 float fthumb
= (float)thumbVisible
;
3218 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3219 if (fpos
< 0.0) fpos
= 0.0;
3221 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3222 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3224 SetScrollPos( orient
, pos
, refresh
);
3228 m_oldVerticalPos
= fpos
;
3230 m_vAdjust
->lower
= 0.0;
3231 m_vAdjust
->upper
= frange
;
3232 m_vAdjust
->value
= fpos
;
3233 m_vAdjust
->step_increment
= 1.0;
3234 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3235 m_vAdjust
->page_size
= fthumb
;
3238 if (orient
== wxHORIZONTAL
)
3239 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3241 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3244 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3246 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3248 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3250 if (orient
== wxHORIZONTAL
)
3252 float fpos
= (float)pos
;
3253 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3254 if (fpos
< 0.0) fpos
= 0.0;
3255 m_oldHorizontalPos
= fpos
;
3257 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3258 m_hAdjust
->value
= fpos
;
3262 float fpos
= (float)pos
;
3263 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3264 if (fpos
< 0.0) fpos
= 0.0;
3265 m_oldVerticalPos
= fpos
;
3267 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3268 m_vAdjust
->value
= fpos
;
3275 if (m_wxwindow
->window
)
3277 if (orient
== wxHORIZONTAL
)
3278 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3280 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3287 int wxWindow::GetScrollThumb( int orient
) const
3289 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3291 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3293 if (orient
== wxHORIZONTAL
)
3294 return (int)(m_hAdjust
->page_size
+0.5);
3296 return (int)(m_vAdjust
->page_size
+0.5);
3299 int wxWindow::GetScrollPos( int orient
) const
3301 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3303 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3305 if (orient
== wxHORIZONTAL
)
3306 return (int)(m_hAdjust
->value
+0.5);
3308 return (int)(m_vAdjust
->value
+0.5);
3311 int wxWindow::GetScrollRange( int orient
) const
3313 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3315 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3317 if (orient
== wxHORIZONTAL
)
3318 return (int)(m_hAdjust
->upper
+0.5);
3320 return (int)(m_vAdjust
->upper
+0.5);
3323 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3325 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3327 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3330 printf( "ScrollWindow: %d %d\n", dx, dy );
3333 gtk_pizza_scroll( GTK_PIZZA(m_wxwindow
), -dx
, -dy
);
3338 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3339 gdk_gc_set_exposures( m_scrollGC, TRUE );
3342 wxNode *node = m_children.First();
3345 wxWindow *child = (wxWindow*) node->Data();
3348 child->GetSize( &sx, &sy );
3349 child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
3350 node = node->Next();
3355 GetClientSize( &cw, &ch );
3356 int w = cw - abs(dx);
3357 int h = ch - abs(dy);
3359 if ((h < 0) || (w < 0))
3367 if (dx < 0) s_x = -dx;
3368 if (dy < 0) s_y = -dy;
3371 if (dx > 0) d_x = dx;
3372 if (dy > 0) d_y = dy;
3374 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
3375 m_wxwindow->window, s_x, s_y, w, h );
3378 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3379 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3380 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3381 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
3383 Refresh( TRUE, &rect );
3388 void wxWindow::SetScrolling(bool scroll
)
3390 m_isScrolling
= g_blockEventsOnScroll
= scroll
;