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
)
227 tmp
+= wxT(" FROM ");
230 wxChar
*s
= new wxChar
[tmp
.Length()+1];
234 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
235 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
240 //-----------------------------------------------------------------------------
241 // missing gdk functions
242 //-----------------------------------------------------------------------------
245 gdk_window_warp_pointer (GdkWindow
*window
,
249 GdkWindowPrivate
*priv
;
252 window
= (GdkWindow
*) &gdk_root_parent
;
254 priv
= (GdkWindowPrivate
*) window
;
256 if (!priv
->destroyed
)
258 XWarpPointer (priv
->xdisplay
,
259 None
, /* not source window -> move from anywhere */
260 priv
->xwindow
, /* dest window */
261 0, 0, 0, 0, /* not source window -> move from anywhere */
266 //-----------------------------------------------------------------------------
268 //-----------------------------------------------------------------------------
270 extern void wxapp_install_idle_handler();
271 extern bool g_isIdle
;
273 //-----------------------------------------------------------------------------
274 // local code (see below)
275 //-----------------------------------------------------------------------------
277 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
285 if (win
->HasScrolling())
287 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
288 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
291 GtkWidget *hscrollbar = scroll_window->hscrollbar;
292 GtkWidget *vscrollbar = scroll_window->vscrollbar;
294 we use this instead: range.slider_width = 11 + 2*2pts edge
297 if (scroll_window
->vscrollbar_visible
)
299 dw
+= 15; /* dw += vscrollbar->allocation.width; */
300 dw
+= scroll_class
->scrollbar_spacing
;
303 if (scroll_window
->hscrollbar_visible
)
305 dh
+= 15; /* dh += hscrollbar->allocation.height; */
306 dh
+= scroll_class
->scrollbar_spacing
;
312 if (GTK_WIDGET_NO_WINDOW (widget
))
314 dx
+= widget
->allocation
.x
;
315 dy
+= widget
->allocation
.y
;
318 if (win
->HasFlag(wxRAISED_BORDER
))
320 gtk_draw_shadow( widget
->style
,
325 win
->m_width
-dw
, win
->m_height
-dh
);
329 if (win
->HasFlag(wxSUNKEN_BORDER
))
331 gtk_draw_shadow( widget
->style
,
336 win
->m_width
-dw
, win
->m_height
-dh
);
340 if (win
->HasFlag(wxSIMPLE_BORDER
))
343 gc
= gdk_gc_new( widget
->window
);
344 gdk_gc_set_foreground( gc
, &widget
->style
->black
);
345 gdk_draw_rectangle( widget
->window
, gc
, FALSE
,
347 win
->m_width
-dw
-1, win
->m_height
-dh
-1 );
353 //-----------------------------------------------------------------------------
354 // "expose_event" of m_widget
355 //-----------------------------------------------------------------------------
357 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
359 if (gdk_event
->count
> 0) return;
360 draw_frame( widget
, win
);
363 //-----------------------------------------------------------------------------
364 // "draw" of m_widget
365 //-----------------------------------------------------------------------------
367 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
369 draw_frame( widget
, win
);
372 //-----------------------------------------------------------------------------
373 // key code mapping routines
374 //-----------------------------------------------------------------------------
376 static long map_to_unmodified_wx_keysym( KeySym keysym
)
383 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
385 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
391 case GDK_Super_R
: key_code
= WXK_ALT
; break;
392 case GDK_Menu
: key_code
= WXK_MENU
; break;
393 case GDK_Help
: key_code
= WXK_HELP
; break;
394 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
395 case GDK_ISO_Left_Tab
:
396 case GDK_Tab
: key_code
= WXK_TAB
; break;
397 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
398 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
399 case GDK_Return
: key_code
= WXK_RETURN
; break;
400 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
401 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
402 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
403 case GDK_Delete
: key_code
= WXK_DELETE
; break;
404 case GDK_Home
: key_code
= WXK_HOME
; break;
405 case GDK_Left
: key_code
= WXK_LEFT
; break;
406 case GDK_Up
: key_code
= WXK_UP
; break;
407 case GDK_Right
: key_code
= WXK_RIGHT
; break;
408 case GDK_Down
: key_code
= WXK_DOWN
; break;
409 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
410 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
411 case GDK_Next
: key_code
= WXK_NEXT
; break;
412 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
413 case GDK_End
: key_code
= WXK_END
; break;
414 case GDK_Begin
: key_code
= WXK_HOME
; break;
415 case GDK_Select
: key_code
= WXK_SELECT
; break;
416 case GDK_Print
: key_code
= WXK_PRINT
; break;
417 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
418 case GDK_Insert
: key_code
= WXK_INSERT
; break;
419 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
421 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
422 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
423 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
424 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
425 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
426 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
427 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
428 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
429 case GDK_KP_8
: key_code
= WXK_NUMPAD8
; break;
430 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
431 case GDK_KP_Space
: key_code
= WXK_NUMPAD_SPACE
; break;
432 case GDK_KP_Tab
: key_code
= WXK_NUMPAD_TAB
; break;
433 case GDK_KP_Enter
: key_code
= WXK_NUMPAD_ENTER
; break;
434 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
435 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
436 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
437 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
438 case GDK_KP_Home
: key_code
= WXK_NUMPAD_HOME
; break;
439 case GDK_KP_Left
: key_code
= WXK_NUMPAD_LEFT
; break;
440 case GDK_KP_Up
: key_code
= WXK_NUMPAD_UP
; break;
441 case GDK_KP_Right
: key_code
= WXK_NUMPAD_RIGHT
; break;
442 case GDK_KP_Down
: key_code
= WXK_NUMPAD_DOWN
; break;
443 case GDK_KP_Prior
: key_code
= WXK_NUMPAD_PRIOR
; break;
444 // case GDK_KP_Page_Up: key_code = WXK_NUMPAD_PAGEUP; break;
445 case GDK_KP_Next
: key_code
= WXK_NUMPAD_NEXT
; break;
446 // case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break;
447 case GDK_KP_End
: key_code
= WXK_NUMPAD_END
; break;
448 case GDK_KP_Begin
: key_code
= WXK_NUMPAD_BEGIN
; break;
449 case GDK_KP_Insert
: key_code
= WXK_NUMPAD_INSERT
; break;
450 case GDK_KP_Delete
: key_code
= WXK_NUMPAD_DELETE
; break;
451 case GDK_KP_Equal
: key_code
= WXK_NUMPAD_EQUAL
; break;
452 case GDK_KP_Multiply
: key_code
= WXK_NUMPAD_MULTIPLY
; break;
453 case GDK_KP_Add
: key_code
= WXK_NUMPAD_ADD
; break;
454 case GDK_KP_Separator
: key_code
= WXK_NUMPAD_SEPARATOR
; break;
455 case GDK_KP_Subtract
: key_code
= WXK_NUMPAD_SUBTRACT
; break;
456 case GDK_KP_Decimal
: key_code
= WXK_NUMPAD_DECIMAL
; break;
457 case GDK_KP_Divide
: key_code
= WXK_NUMPAD_DIVIDE
; break;
459 case GDK_F1
: key_code
= WXK_F1
; break;
460 case GDK_F2
: key_code
= WXK_F2
; break;
461 case GDK_F3
: key_code
= WXK_F3
; break;
462 case GDK_F4
: key_code
= WXK_F4
; break;
463 case GDK_F5
: key_code
= WXK_F5
; break;
464 case GDK_F6
: key_code
= WXK_F6
; break;
465 case GDK_F7
: key_code
= WXK_F7
; break;
466 case GDK_F8
: key_code
= WXK_F8
; break;
467 case GDK_F9
: key_code
= WXK_F9
; break;
468 case GDK_F10
: key_code
= WXK_F10
; break;
469 case GDK_F11
: key_code
= WXK_F11
; break;
470 case GDK_F12
: key_code
= WXK_F12
; break;
475 guint upper
= gdk_keyval_to_upper( (guint
)keysym
);
476 keysym
= (upper
!= 0 ? upper
: keysym
); /* to be MSW compatible */
477 key_code
= (guint
)keysym
;
485 static long map_to_wx_keysym( KeySym keysym
)
491 case GDK_Menu
: key_code
= WXK_MENU
; break;
492 case GDK_Help
: key_code
= WXK_HELP
; break;
493 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
494 case GDK_ISO_Left_Tab
:
495 case GDK_Tab
: key_code
= WXK_TAB
; break;
496 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
497 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
498 case GDK_Return
: key_code
= WXK_RETURN
; break;
499 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
500 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
501 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
502 case GDK_Delete
: key_code
= WXK_DELETE
; break;
503 case GDK_Home
: key_code
= WXK_HOME
; break;
504 case GDK_Left
: key_code
= WXK_LEFT
; break;
505 case GDK_Up
: key_code
= WXK_UP
; break;
506 case GDK_Right
: key_code
= WXK_RIGHT
; break;
507 case GDK_Down
: key_code
= WXK_DOWN
; break;
508 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
509 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
510 case GDK_Next
: key_code
= WXK_NEXT
; break;
511 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
512 case GDK_End
: key_code
= WXK_END
; break;
513 case GDK_Begin
: key_code
= WXK_HOME
; break;
514 case GDK_Select
: key_code
= WXK_SELECT
; break;
515 case GDK_Print
: key_code
= WXK_PRINT
; break;
516 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
517 case GDK_Insert
: key_code
= WXK_INSERT
; break;
518 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
520 case GDK_KP_0
: key_code
= '0'; break;
521 case GDK_KP_1
: key_code
= '1'; break;
522 case GDK_KP_2
: key_code
= '2'; break;
523 case GDK_KP_3
: key_code
= '3'; break;
524 case GDK_KP_4
: key_code
= '4'; break;
525 case GDK_KP_5
: key_code
= '5'; break;
526 case GDK_KP_6
: key_code
= '6'; break;
527 case GDK_KP_7
: key_code
= '7'; break;
528 case GDK_KP_8
: key_code
= '8'; break;
529 case GDK_KP_9
: key_code
= '9'; break;
530 case GDK_KP_Space
: key_code
= ' '; break;
531 case GDK_KP_Tab
: key_code
= WXK_TAB
; break; /* or '\t' ??? */
532 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break; /* or '\r' ??? */
533 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
534 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
535 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
536 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
537 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
538 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
539 case GDK_KP_Up
: key_code
= WXK_UP
; break;
540 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
541 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
542 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
543 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
544 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
545 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
546 case GDK_KP_End
: key_code
= WXK_END
; break;
547 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
548 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
549 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
550 case GDK_KP_Equal
: key_code
= '='; break;
551 case GDK_KP_Multiply
: key_code
= '*'; break;
552 case GDK_KP_Add
: key_code
= '+'; break;
553 case GDK_KP_Separator
: key_code
= ','; break;
554 case GDK_KP_Subtract
: key_code
= '-'; break;
555 case GDK_KP_Decimal
: key_code
= '.'; break;
556 case GDK_KP_Divide
: key_code
= '/'; break;
558 case GDK_F1
: key_code
= WXK_F1
; break;
559 case GDK_F2
: key_code
= WXK_F2
; break;
560 case GDK_F3
: key_code
= WXK_F3
; break;
561 case GDK_F4
: key_code
= WXK_F4
; break;
562 case GDK_F5
: key_code
= WXK_F5
; break;
563 case GDK_F6
: key_code
= WXK_F6
; break;
564 case GDK_F7
: key_code
= WXK_F7
; break;
565 case GDK_F8
: key_code
= WXK_F8
; break;
566 case GDK_F9
: key_code
= WXK_F9
; break;
567 case GDK_F10
: key_code
= WXK_F10
; break;
568 case GDK_F11
: key_code
= WXK_F11
; break;
569 case GDK_F12
: key_code
= WXK_F12
; break;
574 key_code
= (guint
)keysym
;
582 //-----------------------------------------------------------------------------
583 // "expose_event" of m_wxwindow
584 //-----------------------------------------------------------------------------
586 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
591 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
593 gdk_event
->area
.width
,
594 gdk_event
->area
.height
);
596 if (gdk_event
->count
> 0)
600 wxPrintf( "OnExpose from " );
601 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
602 wxPrintf( win->GetClassInfo()->GetClassName() );
603 wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x,
604 (int)gdk_event->area.y,
605 (int)gdk_event->area.width,
606 (int)gdk_event->area.height );
609 wxEraseEvent
eevent( win
->GetId() );
610 eevent
.SetEventObject( win
);
611 win
->GetEventHandler()->ProcessEvent(eevent
);
613 wxPaintEvent
event( win
->GetId() );
614 event
.SetEventObject( win
);
615 win
->GetEventHandler()->ProcessEvent( event
);
617 win
->GetUpdateRegion().Clear();
620 //-----------------------------------------------------------------------------
621 // "draw" of m_wxwindow
622 //-----------------------------------------------------------------------------
624 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
),
625 GdkRectangle
*rect
, wxWindow
*win
)
628 wxapp_install_idle_handler();
633 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
634 rect
->width
, rect
->height
);
637 wxPrintf( "OnDraw from " );
638 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
639 printf( win->GetClassInfo()->GetClassName() );
640 wxPrintf( " %d %d %d %d\n", (int)rect->x,
646 wxEraseEvent
eevent( win
->GetId() );
647 eevent
.SetEventObject( win
);
648 win
->GetEventHandler()->ProcessEvent(eevent
);
650 wxPaintEvent
event( win
->GetId() );
651 event
.SetEventObject( win
);
652 win
->GetEventHandler()->ProcessEvent( event
);
654 win
->GetUpdateRegion().Clear();
657 //-----------------------------------------------------------------------------
658 // "key_press_event" from any window
659 //-----------------------------------------------------------------------------
661 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
664 wxapp_install_idle_handler();
666 if (!win
->m_hasVMT
) return FALSE
;
667 if (g_blockEventsOnDrag
) return FALSE
;
670 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
671 if (gdk_event->state & GDK_SHIFT_MASK)
672 printf( "ShiftDown.\n" );
674 printf( "ShiftUp.\n" );
675 if (gdk_event->state & GDK_CONTROL_MASK)
676 printf( "ControlDown.\n" );
678 printf( "ControlUp.\n" );
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
= (long)gdk_event
->x
;
948 event
.m_y
= (long)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
= (long)gdk_event
->x
;
1075 event
.m_y
= (long)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
= (long)gdk_event
->x
;
1195 event
.m_y
= (long)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
);
1315 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1316 event
.SetEventObject( win
);
1318 if (win
->GetEventHandler()->ProcessEvent( event
))
1320 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1327 //-----------------------------------------------------------------------------
1328 // "focus_out_event"
1329 //-----------------------------------------------------------------------------
1331 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1334 wxapp_install_idle_handler();
1336 if (!win
->m_hasVMT
) return FALSE
;
1337 if (g_blockEventsOnDrag
) return FALSE
;
1339 // if the focus goes out of our app alltogether, OnIdle() will send
1340 // wxActivateEvent, otherwise gtk_window_focus_in_callback() will reset
1341 // g_sendActivateEvent to -1
1342 g_sendActivateEvent
= 0;
1344 g_focusWindow
= (wxWindow
*)NULL
;
1347 printf( "OnKillFocus from " );
1348 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1349 printf( win->GetClassInfo()->GetClassName() );
1353 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1354 event
.SetEventObject( win
);
1356 if (win
->GetEventHandler()->ProcessEvent( event
))
1358 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1365 //-----------------------------------------------------------------------------
1366 // "enter_notify_event"
1367 //-----------------------------------------------------------------------------
1369 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1372 wxapp_install_idle_handler();
1374 if (!win
->m_hasVMT
) return FALSE
;
1375 if (g_blockEventsOnDrag
) return FALSE
;
1377 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1379 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1380 #if (GTK_MINOR_VERSION > 0)
1381 event
.SetTimestamp( gdk_event
->time
);
1383 event
.SetEventObject( win
);
1387 GdkModifierType state
= (GdkModifierType
)0;
1389 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1391 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1392 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1393 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1394 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1395 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1396 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1397 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1399 event
.m_x
= (long)x
;
1400 event
.m_y
= (long)y
;
1402 if (win
->GetEventHandler()->ProcessEvent( event
))
1404 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1411 //-----------------------------------------------------------------------------
1412 // "leave_notify_event"
1413 //-----------------------------------------------------------------------------
1415 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1418 wxapp_install_idle_handler();
1420 if (!win
->m_hasVMT
) return FALSE
;
1421 if (g_blockEventsOnDrag
) return FALSE
;
1423 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1425 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1426 #if (GTK_MINOR_VERSION > 0)
1427 event
.SetTimestamp( gdk_event
->time
);
1429 event
.SetEventObject( win
);
1433 GdkModifierType state
= (GdkModifierType
)0;
1435 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1437 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1438 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1439 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1440 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1441 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1442 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1443 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1445 event
.m_x
= (long)x
;
1446 event
.m_y
= (long)y
;
1448 if (win
->GetEventHandler()->ProcessEvent( event
))
1450 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1457 //-----------------------------------------------------------------------------
1458 // "value_changed" from m_vAdjust
1459 //-----------------------------------------------------------------------------
1461 static void gtk_window_vscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1464 wxapp_install_idle_handler();
1466 if (g_blockEventsOnDrag
) return;
1468 if (!win
->m_hasVMT
) return;
1470 float diff
= adjust
->value
- win
->m_oldVerticalPos
;
1471 if (fabs(diff
) < 0.2) return;
1473 win
->m_oldVerticalPos
= adjust
->value
;
1475 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1476 GtkRange
*range
= GTK_RANGE( scrolledWindow
->vscrollbar
);
1478 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1479 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1480 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1481 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1482 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1484 int value
= (int)(adjust
->value
+0.5);
1486 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1487 event
.SetEventObject( win
);
1488 win
->GetEventHandler()->ProcessEvent( event
);
1491 //-----------------------------------------------------------------------------
1492 // "value_changed" from m_hAdjust
1493 //-----------------------------------------------------------------------------
1495 static void gtk_window_hscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1498 wxapp_install_idle_handler();
1500 if (g_blockEventsOnDrag
) return;
1501 if (!win
->m_hasVMT
) return;
1503 float diff
= adjust
->value
- win
->m_oldHorizontalPos
;
1504 if (fabs(diff
) < 0.2) return;
1506 win
->m_oldHorizontalPos
= adjust
->value
;
1508 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1509 GtkRange
*range
= GTK_RANGE( scrolledWindow
->hscrollbar
);
1511 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1512 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1513 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1514 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1515 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1517 int value
= (int)(adjust
->value
+0.5);
1519 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1520 event
.SetEventObject( win
);
1521 win
->GetEventHandler()->ProcessEvent( event
);
1524 //-----------------------------------------------------------------------------
1525 // "changed" from m_vAdjust
1526 //-----------------------------------------------------------------------------
1528 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1531 wxapp_install_idle_handler();
1533 if (g_blockEventsOnDrag
) return;
1534 if (!win
->m_hasVMT
) return;
1536 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1537 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1539 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1540 event
.SetEventObject( win
);
1541 win
->GetEventHandler()->ProcessEvent( event
);
1544 //-----------------------------------------------------------------------------
1545 // "changed" from m_hAdjust
1546 //-----------------------------------------------------------------------------
1548 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1551 wxapp_install_idle_handler();
1553 if (g_blockEventsOnDrag
) return;
1554 if (!win
->m_hasVMT
) return;
1556 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1557 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1559 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1560 event
.SetEventObject( win
);
1561 win
->GetEventHandler()->ProcessEvent( event
);
1564 //-----------------------------------------------------------------------------
1565 // "button_press_event" from scrollbar
1566 //-----------------------------------------------------------------------------
1568 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1569 GdkEventButton
*WXUNUSED(gdk_event
),
1573 wxapp_install_idle_handler();
1575 // don't test here as we can release the mouse while being over
1576 // a different window than the slider
1578 // if (gdk_event->window != widget->slider) return FALSE;
1580 win
->SetScrolling( TRUE
);
1585 //-----------------------------------------------------------------------------
1586 // "button_release_event" from scrollbar
1587 //-----------------------------------------------------------------------------
1589 static gint
gtk_scrollbar_button_release_callback( GtkRange
*WXUNUSED(widget
),
1590 GdkEventButton
*WXUNUSED(gdk_event
),
1594 // don't test here as we can release the mouse while being over
1595 // a different window than the slider
1597 // if (gdk_event->window != widget->slider) return FALSE;
1599 win
->SetScrolling( FALSE
);
1604 // ----------------------------------------------------------------------------
1605 // this wxWindowBase function is implemented here (in platform-specific file)
1606 // because it is static and so couldn't be made virtual
1607 // ----------------------------------------------------------------------------
1609 wxWindow
*wxWindowBase::FindFocus()
1611 return g_focusWindow
;
1614 //-----------------------------------------------------------------------------
1615 // "realize" from m_widget
1616 //-----------------------------------------------------------------------------
1618 /* we cannot set colours and fonts before the widget has
1619 been realized, so we do this directly after realization */
1622 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1625 wxapp_install_idle_handler();
1627 if (win
->m_delayedFont
)
1628 win
->SetFont( win
->GetFont() );
1630 if (win
->m_delayedBackgroundColour
)
1631 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1633 if (win
->m_delayedForegroundColour
)
1634 win
->SetForegroundColour( win
->GetForegroundColour() );
1636 wxWindowCreateEvent
event( win
);
1637 event
.SetEventObject( win
);
1638 win
->GetEventHandler()->ProcessEvent( event
);
1643 //-----------------------------------------------------------------------------
1644 // InsertChild for wxWindow.
1645 //-----------------------------------------------------------------------------
1647 /* Callback for wxWindow. This very strange beast has to be used because
1648 * C++ has no virtual methods in a constructor. We have to emulate a
1649 * virtual function here as wxNotebook requires a different way to insert
1650 * a child in it. I had opted for creating a wxNotebookPage window class
1651 * which would have made this superfluous (such in the MDI window system),
1652 * but no-one was listening to me... */
1654 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1656 /* the window might have been scrolled already, do we
1657 have to adapt the position */
1658 GtkPizza
*pizza
= GTK_PIZZA(parent
->m_wxwindow
);
1659 child
->m_x
+= pizza
->xoffset
;
1660 child
->m_y
+= pizza
->yoffset
;
1662 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
1663 GTK_WIDGET(child
->m_widget
),
1670 //-----------------------------------------------------------------------------
1672 //-----------------------------------------------------------------------------
1674 wxWindow
* wxGetActiveWindow()
1676 return g_focusWindow
;
1679 //-----------------------------------------------------------------------------
1681 //-----------------------------------------------------------------------------
1683 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1685 void wxWindow::Init()
1691 m_widget
= (GtkWidget
*) NULL
;
1692 m_wxwindow
= (GtkWidget
*) NULL
;
1702 m_needParent
= TRUE
;
1703 m_isBeingDeleted
= FALSE
;
1706 m_nativeSizeEvent
= FALSE
;
1708 m_hasScrolling
= FALSE
;
1709 m_isScrolling
= FALSE
;
1711 m_hAdjust
= (GtkAdjustment
*) NULL
;
1712 m_vAdjust
= (GtkAdjustment
*) NULL
;
1713 m_oldHorizontalPos
= 0.0;
1714 m_oldVerticalPos
= 0.0;
1717 m_widgetStyle
= (GtkStyle
*) NULL
;
1719 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1721 m_isStaticBox
= FALSE
;
1722 m_isRadioButton
= FALSE
;
1724 m_acceptsFocus
= FALSE
;
1726 m_cursor
= *wxSTANDARD_CURSOR
;
1729 wxWindow::wxWindow()
1734 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1735 const wxPoint
&pos
, const wxSize
&size
,
1736 long style
, const wxString
&name
)
1740 Create( parent
, id
, pos
, size
, style
, name
);
1743 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1744 const wxPoint
&pos
, const wxSize
&size
,
1745 long style
, const wxString
&name
)
1747 if (!PreCreation( parent
, pos
, size
) ||
1748 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
1750 wxFAIL_MSG( wxT("wxWindow creation failed") );
1754 m_insertCallback
= wxInsertChildInWindow
;
1756 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1757 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1760 debug_focus_in( m_widget
, wxT("wxWindow::m_widget"), name
);
1763 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1766 debug_focus_in( scrolledWindow
->hscrollbar
, wxT("wxWindow::hsrcollbar"), name
);
1767 debug_focus_in( scrolledWindow
->vscrollbar
, wxT("wxWindow::vsrcollbar"), name
);
1770 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1771 scroll_class
->scrollbar_spacing
= 0;
1773 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1775 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1776 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1778 m_wxwindow
= gtk_pizza_new();
1781 debug_focus_in( m_wxwindow
, wxT("wxWindow::m_wxwindow"), name
);
1784 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1786 #if (GTK_MINOR_VERSION > 0)
1787 GtkPizza
*pizza
= GTK_PIZZA(m_wxwindow
);
1789 if (HasFlag(wxRAISED_BORDER
))
1791 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_OUT
);
1793 else if (HasFlag(wxSUNKEN_BORDER
))
1795 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_IN
);
1797 else if (HasFlag(wxSIMPLE_BORDER
))
1799 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_THIN
);
1803 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_NONE
);
1805 #else // GTK_MINOR_VERSION == 0
1806 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1808 if (HasFlag(wxRAISED_BORDER
))
1810 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1812 else if (HasFlag(wxSUNKEN_BORDER
))
1814 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1818 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1820 #endif // GTK_MINOR_VERSION
1822 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1823 m_acceptsFocus
= TRUE
;
1825 #if (GTK_MINOR_VERSION == 0)
1826 // shut the viewport up
1827 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1828 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1829 #endif // GTK_MINOR_VERSION == 0
1831 // I _really_ don't want scrollbars in the beginning
1832 m_vAdjust
->lower
= 0.0;
1833 m_vAdjust
->upper
= 1.0;
1834 m_vAdjust
->value
= 0.0;
1835 m_vAdjust
->step_increment
= 1.0;
1836 m_vAdjust
->page_increment
= 1.0;
1837 m_vAdjust
->page_size
= 5.0;
1838 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1839 m_hAdjust
->lower
= 0.0;
1840 m_hAdjust
->upper
= 1.0;
1841 m_hAdjust
->value
= 0.0;
1842 m_hAdjust
->step_increment
= 1.0;
1843 m_hAdjust
->page_increment
= 1.0;
1844 m_hAdjust
->page_size
= 5.0;
1845 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1847 // these handlers block mouse events to any window during scrolling such as
1848 // motion events and prevent GTK and wxWindows from fighting over where the
1851 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1852 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1854 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1855 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1857 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1858 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1860 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1861 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1863 // these handlers get notified when screen updates are required either when
1864 // scrolling or when the window size (and therefore scrollbar configuration)
1867 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1868 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1869 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1870 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1872 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1873 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1874 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1875 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1877 gtk_widget_show( m_wxwindow
);
1880 m_parent
->DoAddChild( this );
1889 wxWindow::~wxWindow()
1891 m_isBeingDeleted
= TRUE
;
1900 m_parent
->RemoveChild( this );
1904 gtk_style_unref( m_widgetStyle
);
1905 m_widgetStyle
= (GtkStyle
*) NULL
;
1910 gtk_widget_destroy( m_wxwindow
);
1911 m_wxwindow
= (GtkWidget
*) NULL
;
1916 gtk_widget_destroy( m_widget
);
1917 m_widget
= (GtkWidget
*) NULL
;
1921 bool wxWindow::PreCreation( wxWindow
*parent
, const wxPoint
&pos
, const wxSize
&size
)
1923 wxCHECK_MSG( !m_needParent
|| parent
, FALSE
, wxT("Need complete parent.") );
1925 /* this turns -1 into 20 so that a minimal window is
1926 visible even although -1,-1 has been given as the
1927 size of the window. the same trick is used in other
1928 ports and should make debugging easier */
1929 m_width
= WidthDefault(size
.x
);
1930 m_height
= HeightDefault(size
.y
);
1935 /* some reasonable defaults */
1940 m_x
= (gdk_screen_width () - m_width
) / 2;
1941 if (m_x
< 10) m_x
= 10;
1945 m_y
= (gdk_screen_height () - m_height
) / 2;
1946 if (m_y
< 10) m_y
= 10;
1953 void wxWindow::PostCreation()
1955 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
1961 /* these get reported to wxWindows -> wxPaintEvent */
1962 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1963 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1965 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1966 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1969 #if (GTK_MINOR_VERSION > 0)
1970 /* these are called when the "sunken" or "raised" borders are drawn */
1971 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1972 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1974 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1975 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1979 GtkWidget
*connect_widget
= GetConnectWidget();
1981 ConnectWidget( connect_widget
);
1983 /* we cannot set colours, fonts and cursors before the widget has
1984 been realized, so we do this directly after realization */
1985 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1986 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1991 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1993 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1994 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1996 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1997 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1999 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
2000 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
2002 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
2003 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
2005 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
2006 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
2008 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
2009 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2011 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
2012 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2014 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
2015 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
2017 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
2018 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
2021 bool wxWindow::Destroy()
2023 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2027 return wxWindowBase::Destroy();
2030 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
2032 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2033 wxASSERT_MSG( (m_parent
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") );
2035 if (m_resizing
) return; /* I don't like recursions */
2038 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
2040 /* don't set the size for children of wxNotebook, just take the values. */
2048 GtkPizza
*pizza
= GTK_PIZZA(m_parent
->m_wxwindow
);
2050 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
2052 if (x
!= -1) m_x
= x
+ pizza
->xoffset
;
2053 if (y
!= -1) m_y
= y
+ pizza
->yoffset
;
2054 if (width
!= -1) m_width
= width
;
2055 if (height
!= -1) m_height
= height
;
2059 m_x
= x
+ pizza
->xoffset
;
2060 m_y
= y
+ pizza
->yoffset
;
2065 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2067 if (width
== -1) m_width
= 80;
2070 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2072 if (height
== -1) m_height
= 26;
2075 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2076 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2077 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2078 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2081 int bottom_border
= 0;
2083 if (GTK_WIDGET_CAN_DEFAULT(m_widget
))
2085 /* the default button has a border around it */
2090 gtk_pizza_set_size( GTK_PIZZA(m_parent
->m_wxwindow
),
2095 m_height
+border
+bottom_border
);
2099 wxPrintf( "OnSize sent from " );
2100 if (GetClassInfo() && GetClassInfo()->GetClassName())
2101 wxPrintf( GetClassInfo()->GetClassName() );
2102 wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height );
2105 if (!m_nativeSizeEvent
)
2107 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2108 event
.SetEventObject( this );
2109 GetEventHandler()->ProcessEvent( event
);
2115 void wxWindow::OnInternalIdle()
2117 if ( g_sendActivateEvent
!= -1 )
2119 bool activate
= g_sendActivateEvent
!= 0;
2122 g_sendActivateEvent
= -1;
2124 wxActivateEvent
event(wxEVT_ACTIVATE
, activate
, GetId());
2125 event
.SetEventObject(this);
2127 (void)GetEventHandler()->ProcessEvent(event
);
2130 wxCursor cursor
= m_cursor
;
2131 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2135 /* I now set the cursor anew in every OnInternalIdle call
2136 as setting the cursor in a parent window also effects the
2137 windows above so that checking for the current cursor is
2142 GdkWindow
*window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2144 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2146 if (!g_globalCursor
.Ok())
2147 cursor
= *wxSTANDARD_CURSOR
;
2149 window
= m_widget
->window
;
2150 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2151 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2157 GdkWindow
*window
= m_widget
->window
;
2158 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2159 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2167 void wxWindow::DoGetSize( int *width
, int *height
) const
2169 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2171 if (width
) (*width
) = m_width
;
2172 if (height
) (*height
) = m_height
;
2175 void wxWindow::DoSetClientSize( int width
, int height
)
2177 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2181 SetSize( width
, height
);
2188 #if (GTK_MINOR_VERSION == 0)
2189 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2193 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2194 #if 0 // unused - if this is ok, just remove this line (VZ)
2195 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2198 GtkWidget
*viewport
= scroll_window
->viewport
;
2199 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2201 dw
+= 2 * viewport_class
->xthickness
;
2202 dh
+= 2 * viewport_class
->ythickness
;
2206 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2208 /* when using GTK 1.2 we set the shadow border size to 2 */
2212 if (HasFlag(wxSIMPLE_BORDER
))
2214 /* when using GTK 1.2 we set the simple border size to 1 */
2223 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2224 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2226 we use this instead: range.slider_width = 11 + 2*2pts edge
2229 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2230 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2232 if (scroll_window
->vscrollbar_visible
)
2234 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2235 dw
+= scroll_class
->scrollbar_spacing
;
2238 if (scroll_window
->hscrollbar_visible
)
2240 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2241 dh
+= scroll_class
->scrollbar_spacing
;
2245 SetSize( width
+dw
, height
+dh
);
2249 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2251 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2255 if (width
) (*width
) = m_width
;
2256 if (height
) (*height
) = m_height
;
2263 #if (GTK_MINOR_VERSION == 0)
2264 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2268 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2269 #if 0 // unused - if this is ok, just remove this line (VZ)
2270 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2273 GtkWidget
*viewport
= scroll_window
->viewport
;
2274 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2276 dw
+= 2 * viewport_class
->xthickness
;
2277 dh
+= 2 * viewport_class
->ythickness
;
2281 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2283 /* when using GTK 1.2 we set the shadow border size to 2 */
2287 if (HasFlag(wxSIMPLE_BORDER
))
2289 /* when using GTK 1.2 we set the simple border size to 1 */
2297 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2298 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2300 we use this instead: range.slider_width = 11 + 2*2pts edge
2303 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2304 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2306 if (scroll_window
->vscrollbar_visible
)
2308 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2309 dw
+= scroll_class
->scrollbar_spacing
;
2312 if (scroll_window
->hscrollbar_visible
)
2314 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2315 dh
+= scroll_class
->scrollbar_spacing
;
2319 if (width
) (*width
) = m_width
- dw
;
2320 if (height
) (*height
) = m_height
- dh
;
2324 void wxWindow::DoGetPosition( int *x
, int *y
) const
2326 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2330 if (m_parent
&& m_parent
->m_wxwindow
)
2332 GtkPizza
*pizza
= GTK_PIZZA(m_parent
->m_wxwindow
);
2333 dx
= pizza
->xoffset
;
2334 dy
= pizza
->yoffset
;
2337 if (x
) (*x
) = m_x
- dx
;
2338 if (y
) (*y
) = m_y
- dy
;
2341 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2343 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2345 if (!m_widget
->window
) return;
2347 GdkWindow
*source
= (GdkWindow
*) NULL
;
2349 source
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2351 source
= m_widget
->window
;
2355 gdk_window_get_origin( source
, &org_x
, &org_y
);
2359 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2361 org_x
+= m_widget
->allocation
.x
;
2362 org_y
+= m_widget
->allocation
.y
;
2370 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2372 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2374 if (!m_widget
->window
) return;
2376 GdkWindow
*source
= (GdkWindow
*) NULL
;
2378 source
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2380 source
= m_widget
->window
;
2384 gdk_window_get_origin( source
, &org_x
, &org_y
);
2388 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2390 org_x
+= m_widget
->allocation
.x
;
2391 org_y
+= m_widget
->allocation
.y
;
2399 bool wxWindow::Show( bool show
)
2401 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2403 if (!wxWindowBase::Show(show
))
2410 gtk_widget_show( m_widget
);
2412 gtk_widget_hide( m_widget
);
2417 bool wxWindow::Enable( bool enable
)
2419 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2421 if (!wxWindowBase::Enable(enable
))
2427 gtk_widget_set_sensitive( m_widget
, enable
);
2429 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2434 int wxWindow::GetCharHeight() const
2436 wxCHECK_MSG( (m_widget
!= NULL
), 12, wxT("invalid window") );
2438 wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") );
2440 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2442 return font
->ascent
+ font
->descent
;
2445 int wxWindow::GetCharWidth() const
2447 wxCHECK_MSG( (m_widget
!= NULL
), 8, wxT("invalid window") );
2449 wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") );
2451 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2453 return gdk_string_width( font
, "H" );
2456 void wxWindow::GetTextExtent( const wxString
& string
,
2460 int *externalLeading
,
2461 const wxFont
*theFont
) const
2463 wxFont fontToUse
= m_font
;
2464 if (theFont
) fontToUse
= *theFont
;
2466 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
2468 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2469 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2470 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2471 if (descent
) (*descent
) = font
->descent
;
2472 if (externalLeading
) (*externalLeading
) = 0; // ??
2475 void wxWindow::SetFocus()
2477 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2481 if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow
))
2482 gtk_widget_grab_focus (m_wxwindow
);
2488 if (GTK_WIDGET_CAN_FOCUS(m_widget
) && !GTK_WIDGET_HAS_FOCUS (m_widget
) )
2490 gtk_widget_grab_focus (m_widget
);
2492 else if (GTK_IS_CONTAINER(m_widget
))
2494 gtk_container_focus( GTK_CONTAINER(m_widget
), GTK_DIR_TAB_FORWARD
);
2503 bool wxWindow::AcceptsFocus() const
2505 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2508 bool wxWindow::Reparent( wxWindowBase
*newParentBase
)
2510 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2512 wxWindow
*oldParent
= m_parent
,
2513 *newParent
= (wxWindow
*)newParentBase
;
2515 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2517 if ( !wxWindowBase::Reparent(newParent
) )
2520 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2522 /* prevent GTK from deleting the widget arbitrarily */
2523 gtk_widget_ref( m_widget
);
2527 gtk_container_remove( GTK_CONTAINER(m_widget
->parent
), m_widget
);
2530 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2534 /* insert GTK representation */
2535 (*(newParent
->m_insertCallback
))(newParent
, this);
2538 /* reverse: prevent GTK from deleting the widget arbitrarily */
2539 gtk_widget_unref( m_widget
);
2544 void wxWindow::DoAddChild(wxWindow
*child
)
2546 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2548 wxASSERT_MSG( (child
!= NULL
), wxT("invalid child window") );
2550 wxASSERT_MSG( (m_insertCallback
!= NULL
), wxT("invalid child insertion function") );
2555 /* insert GTK representation */
2556 (*m_insertCallback
)(this, child
);
2559 void wxWindow::Raise()
2561 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2563 if (!m_widget
->window
) return;
2565 gdk_window_raise( m_widget
->window
);
2568 void wxWindow::Lower()
2570 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2572 if (!m_widget
->window
) return;
2574 gdk_window_lower( m_widget
->window
);
2577 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2579 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2581 return wxWindowBase::SetCursor( cursor
);
2584 void wxWindow::WarpPointer( int x
, int y
)
2586 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2588 /* we provide this function ourselves as it is
2589 missing in GDK (top of this file) */
2591 GdkWindow
*window
= (GdkWindow
*) NULL
;
2593 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2595 window
= GetConnectWidget()->window
;
2598 gdk_window_warp_pointer( window
, x
, y
);
2601 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2603 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2605 if (!m_widget
->window
) return;
2607 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2611 gdk_window_clear_area( GTK_PIZZA(m_wxwindow
)->bin_window
,
2613 rect
->width
, rect
->height
);
2617 gdk_window_clear( GTK_PIZZA(m_wxwindow
)->bin_window
);
2621 /* there is no GTK equivalent of "draw only, don't clear" so we
2622 invent our own in the GtkPizza widget */
2628 GtkPizza
*pizza
= GTK_PIZZA(m_wxwindow
);
2629 gboolean old_clear
= pizza
->clear_on_draw
;
2630 gtk_pizza_set_clear( pizza
, FALSE
);
2632 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2634 gtk_pizza_set_clear( pizza
, old_clear
);
2637 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2641 GdkRectangle gdk_rect
;
2642 gdk_rect
.x
= rect
->x
;
2643 gdk_rect
.y
= rect
->y
;
2644 gdk_rect
.width
= rect
->width
;
2645 gdk_rect
.height
= rect
->height
;
2649 GtkPizza
*pizza
= GTK_PIZZA(m_wxwindow
);
2650 gboolean old_clear
= pizza
->clear_on_draw
;
2651 gtk_pizza_set_clear( pizza
, FALSE
);
2653 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2655 gtk_pizza_set_clear( pizza
, old_clear
);
2658 gtk_widget_draw( m_widget
, &gdk_rect
);
2662 void wxWindow::Clear()
2664 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2666 if (!m_widget
->window
) return;
2668 if (m_wxwindow
&& m_wxwindow
->window
)
2670 gdk_window_clear( m_wxwindow
->window
);
2675 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2677 wxWindowBase::DoSetToolTip(tip
);
2680 m_tooltip
->Apply( this );
2683 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2685 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2687 #endif // wxUSE_TOOLTIPS
2689 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2691 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2693 if (!wxWindowBase::SetBackgroundColour(colour
))
2695 // don't leave if the GTK widget has just
2697 if (!m_delayedBackgroundColour
) return FALSE
;
2700 GdkWindow
*window
= (GdkWindow
*) NULL
;
2702 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2704 window
= GetConnectWidget()->window
;
2708 // indicate that a new style has been set
2709 // but it couldn't get applied as the
2710 // widget hasn't been realized yet.
2711 m_delayedBackgroundColour
= TRUE
;
2713 // pretend we have done something
2719 /* wxMSW doesn't clear the window here. I don't do that either to
2720 provide compatibility. call Clear() to do the job. */
2722 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2723 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2726 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2727 if (sysbg
== m_backgroundColour
)
2729 m_backgroundColour
= wxNullColour
;
2731 m_backgroundColour
= sysbg
;
2741 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2743 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2745 if (!wxWindowBase::SetForegroundColour(colour
))
2747 // don't leave if the GTK widget has just
2749 if (!m_delayedForegroundColour
) return FALSE
;
2752 GdkWindow
*window
= (GdkWindow
*) NULL
;
2754 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2756 window
= GetConnectWidget()->window
;
2760 // indicate that a new style has been set
2761 // but it couldn't get applied as the
2762 // widget hasn't been realized yet.
2763 m_delayedForegroundColour
= TRUE
;
2765 // pretend we have done something
2769 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2770 if ( sysbg
== m_backgroundColour
)
2772 m_backgroundColour
= wxNullColour
;
2774 m_backgroundColour
= sysbg
;
2784 GtkStyle
*wxWindow::GetWidgetStyle()
2786 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2788 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2790 return m_widgetStyle
;
2793 void wxWindow::SetWidgetStyle()
2795 GtkStyle
*style
= GetWidgetStyle();
2797 gdk_font_unref( style
->font
);
2798 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2800 if (m_foregroundColour
.Ok())
2802 m_foregroundColour
.CalcPixel( gtk_widget_get_colormap( m_widget
) );
2803 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2804 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2805 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2808 if (m_backgroundColour
.Ok())
2810 m_backgroundColour
.CalcPixel( gtk_widget_get_colormap( m_widget
) );
2811 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2812 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2813 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2814 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2815 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2816 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2817 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2818 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2822 void wxWindow::ApplyWidgetStyle()
2826 //-----------------------------------------------------------------------------
2827 // Pop-up menu stuff
2828 //-----------------------------------------------------------------------------
2830 static void gtk_pop_hide_callback( GtkWidget
*WXUNUSED(widget
), bool* is_waiting
)
2832 *is_waiting
= FALSE
;
2835 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2837 menu
->SetInvokingWindow( win
);
2838 wxMenuItemList::Node
*node
= menu
->GetMenuItems().GetFirst();
2841 wxMenuItem
*menuitem
= node
->GetData();
2842 if (menuitem
->IsSubMenu())
2844 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2847 node
= node
->GetNext();
2851 static gint gs_pop_x
= 0;
2852 static gint gs_pop_y
= 0;
2854 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2858 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2863 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
2865 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2867 wxCHECK_MSG( menu
!= NULL
, FALSE
, wxT("invalid popup-menu") );
2869 SetInvokingWindow( menu
, this );
2876 bool is_waiting
= TRUE
;
2878 gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide",
2879 GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting
);
2882 GTK_MENU(menu
->m_menu
),
2883 (GtkWidget
*) NULL
, // parent menu shell
2884 (GtkWidget
*) NULL
, // parent menu item
2885 (GtkMenuPositionFunc
) pop_pos_callback
,
2886 (gpointer
) this, // client data
2887 0, // button used to activate it
2888 gs_timeLastClick
// the time of activation
2893 while (gtk_events_pending())
2894 gtk_main_iteration();
2900 #if wxUSE_DRAG_AND_DROP
2902 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2904 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2906 GtkWidget
*dnd_widget
= GetConnectWidget();
2908 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2910 if (m_dropTarget
) delete m_dropTarget
;
2911 m_dropTarget
= dropTarget
;
2913 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2916 #endif // wxUSE_DRAG_AND_DROP
2918 GtkWidget
* wxWindow::GetConnectWidget()
2920 GtkWidget
*connect_widget
= m_widget
;
2921 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2923 return connect_widget
;
2926 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2929 return (window
== GTK_PIZZA(m_wxwindow
)->bin_window
);
2931 return (window
== m_widget
->window
);
2934 bool wxWindow::SetFont( const wxFont
&font
)
2936 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2938 if (!wxWindowBase::SetFont(font
))
2943 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2944 if ( sysbg
== m_backgroundColour
)
2946 m_backgroundColour
= wxNullColour
;
2948 m_backgroundColour
= sysbg
;
2958 void wxWindow::CaptureMouse()
2960 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2962 wxCHECK_RET( g_captureWindow
== NULL
, wxT("CaptureMouse called twice") );
2964 GdkWindow
*window
= (GdkWindow
*) NULL
;
2966 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2968 window
= GetConnectWidget()->window
;
2970 if (!window
) return;
2972 gdk_pointer_grab( window
, FALSE
,
2974 (GDK_BUTTON_PRESS_MASK
|
2975 GDK_BUTTON_RELEASE_MASK
|
2976 GDK_POINTER_MOTION_HINT_MASK
|
2977 GDK_POINTER_MOTION_MASK
),
2979 m_cursor
.GetCursor(),
2980 (guint32
)GDK_CURRENT_TIME
);
2981 g_captureWindow
= this;
2984 void wxWindow::ReleaseMouse()
2986 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2988 wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") );
2990 GdkWindow
*window
= (GdkWindow
*) NULL
;
2992 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2994 window
= GetConnectWidget()->window
;
2999 gdk_pointer_ungrab ( (guint32
)GDK_CURRENT_TIME
);
3000 g_captureWindow
= (wxWindow
*) NULL
;
3003 bool wxWindow::IsRetained() const
3008 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3009 int range
, bool refresh
)
3011 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3013 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3015 m_hasScrolling
= TRUE
;
3017 if (orient
== wxHORIZONTAL
)
3019 float fpos
= (float)pos
;
3020 float frange
= (float)range
;
3021 float fthumb
= (float)thumbVisible
;
3022 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3023 if (fpos
< 0.0) fpos
= 0.0;
3025 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3026 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3028 SetScrollPos( orient
, pos
, refresh
);
3032 m_oldHorizontalPos
= fpos
;
3034 m_hAdjust
->lower
= 0.0;
3035 m_hAdjust
->upper
= frange
;
3036 m_hAdjust
->value
= fpos
;
3037 m_hAdjust
->step_increment
= 1.0;
3038 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3039 m_hAdjust
->page_size
= fthumb
;
3043 float fpos
= (float)pos
;
3044 float frange
= (float)range
;
3045 float fthumb
= (float)thumbVisible
;
3046 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3047 if (fpos
< 0.0) fpos
= 0.0;
3049 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3050 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3052 SetScrollPos( orient
, pos
, refresh
);
3056 m_oldVerticalPos
= fpos
;
3058 m_vAdjust
->lower
= 0.0;
3059 m_vAdjust
->upper
= frange
;
3060 m_vAdjust
->value
= fpos
;
3061 m_vAdjust
->step_increment
= 1.0;
3062 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3063 m_vAdjust
->page_size
= fthumb
;
3066 if (orient
== wxHORIZONTAL
)
3067 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3069 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3072 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3074 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3076 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3078 if (orient
== wxHORIZONTAL
)
3080 float fpos
= (float)pos
;
3081 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3082 if (fpos
< 0.0) fpos
= 0.0;
3083 m_oldHorizontalPos
= fpos
;
3085 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3086 m_hAdjust
->value
= fpos
;
3090 float fpos
= (float)pos
;
3091 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3092 if (fpos
< 0.0) fpos
= 0.0;
3093 m_oldVerticalPos
= fpos
;
3095 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3096 m_vAdjust
->value
= fpos
;
3103 if (m_wxwindow
->window
)
3105 if (orient
== wxHORIZONTAL
)
3106 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3108 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3115 int wxWindow::GetScrollThumb( int orient
) const
3117 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3119 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3121 if (orient
== wxHORIZONTAL
)
3122 return (int)(m_hAdjust
->page_size
+0.5);
3124 return (int)(m_vAdjust
->page_size
+0.5);
3127 int wxWindow::GetScrollPos( int orient
) const
3129 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3131 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3133 if (orient
== wxHORIZONTAL
)
3134 return (int)(m_hAdjust
->value
+0.5);
3136 return (int)(m_vAdjust
->value
+0.5);
3139 int wxWindow::GetScrollRange( int orient
) const
3141 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3143 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3145 if (orient
== wxHORIZONTAL
)
3146 return (int)(m_hAdjust
->upper
+0.5);
3148 return (int)(m_vAdjust
->upper
+0.5);
3151 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3153 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3155 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3157 gtk_pizza_scroll( GTK_PIZZA(m_wxwindow
), -dx
, -dy
);
3162 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3163 gdk_gc_set_exposures( m_scrollGC, TRUE );
3166 wxNode *node = m_children.First();
3169 wxWindow *child = (wxWindow*) node->Data();
3172 child->GetSize( &sx, &sy );
3173 child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
3174 node = node->Next();
3179 GetClientSize( &cw, &ch );
3180 int w = cw - abs(dx);
3181 int h = ch - abs(dy);
3183 if ((h < 0) || (w < 0))
3191 if (dx < 0) s_x = -dx;
3192 if (dy < 0) s_y = -dy;
3195 if (dx > 0) d_x = dx;
3196 if (dy > 0) d_y = dy;
3198 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
3199 m_wxwindow->window, s_x, s_y, w, h );
3202 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3203 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3204 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3205 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
3207 Refresh( TRUE, &rect );
3212 void wxWindow::SetScrolling(bool scroll
)
3214 m_isScrolling
= g_blockEventsOnScroll
= scroll
;