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
;
188 wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
190 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
191 the last click here */
192 static guint32 gs_timeLastClick
= 0;
194 //-----------------------------------------------------------------------------
196 //-----------------------------------------------------------------------------
200 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
201 GdkEvent
*WXUNUSED(event
),
202 const wxChar
*WXUNUSED(name
) )
205 static bool s_done = FALSE;
208 wxLog::AddTraceMask("focus");
211 wxLogTrace(wxT("FOCUS NOW AT: %s"), name);
217 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
220 tmp
+= wxT(" FROM ");
223 wxChar
*s
= new wxChar
[tmp
.Length()+1];
227 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
228 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
233 //-----------------------------------------------------------------------------
234 // missing gdk functions
235 //-----------------------------------------------------------------------------
238 gdk_window_warp_pointer (GdkWindow
*window
,
242 GdkWindowPrivate
*priv
;
245 window
= (GdkWindow
*) &gdk_root_parent
;
247 priv
= (GdkWindowPrivate
*) window
;
249 if (!priv
->destroyed
)
251 XWarpPointer (priv
->xdisplay
,
252 None
, /* not source window -> move from anywhere */
253 priv
->xwindow
, /* dest window */
254 0, 0, 0, 0, /* not source window -> move from anywhere */
259 //-----------------------------------------------------------------------------
261 //-----------------------------------------------------------------------------
263 extern void wxapp_install_idle_handler();
264 extern bool g_isIdle
;
266 //-----------------------------------------------------------------------------
267 // local code (see below)
268 //-----------------------------------------------------------------------------
270 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
278 if (win
->HasScrolling())
280 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
281 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
284 GtkWidget *hscrollbar = scroll_window->hscrollbar;
285 GtkWidget *vscrollbar = scroll_window->vscrollbar;
287 we use this instead: range.slider_width = 11 + 2*2pts edge
290 if (scroll_window
->vscrollbar_visible
)
292 dw
+= 15; /* dw += vscrollbar->allocation.width; */
293 dw
+= scroll_class
->scrollbar_spacing
;
296 if (scroll_window
->hscrollbar_visible
)
298 dh
+= 15; /* dh += hscrollbar->allocation.height; */
299 dh
+= scroll_class
->scrollbar_spacing
;
305 if (GTK_WIDGET_NO_WINDOW (widget
))
307 dx
+= widget
->allocation
.x
;
308 dy
+= widget
->allocation
.y
;
311 if (win
->HasFlag(wxRAISED_BORDER
))
313 gtk_draw_shadow( widget
->style
,
318 win
->m_width
-dw
, win
->m_height
-dh
);
322 if (win
->HasFlag(wxSUNKEN_BORDER
))
324 gtk_draw_shadow( widget
->style
,
329 win
->m_width
-dw
, win
->m_height
-dh
);
333 if (win
->HasFlag(wxSIMPLE_BORDER
))
336 gc
= gdk_gc_new( widget
->window
);
337 gdk_gc_set_foreground( gc
, &widget
->style
->black
);
338 gdk_draw_rectangle( widget
->window
, gc
, FALSE
,
340 win
->m_width
-dw
-1, win
->m_height
-dh
-1 );
346 //-----------------------------------------------------------------------------
347 // "expose_event" of m_widget
348 //-----------------------------------------------------------------------------
350 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
352 if (gdk_event
->count
> 0) return;
353 draw_frame( widget
, win
);
356 //-----------------------------------------------------------------------------
357 // "draw" of m_widget
358 //-----------------------------------------------------------------------------
360 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
362 draw_frame( widget
, win
);
365 //-----------------------------------------------------------------------------
366 // key code mapping routines
367 //-----------------------------------------------------------------------------
369 static long map_to_unmodified_wx_keysym( KeySym keysym
)
376 case GDK_Shift_R
: key_code
= WXK_SHIFT
; break;
378 case GDK_Control_R
: key_code
= WXK_CONTROL
; break;
384 case GDK_Super_R
: key_code
= WXK_ALT
; break;
385 case GDK_Menu
: key_code
= WXK_MENU
; break;
386 case GDK_Help
: key_code
= WXK_HELP
; break;
387 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
388 case GDK_ISO_Left_Tab
:
389 case GDK_Tab
: key_code
= WXK_TAB
; break;
390 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
391 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
392 case GDK_Return
: key_code
= WXK_RETURN
; break;
393 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
394 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
395 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
396 case GDK_Delete
: key_code
= WXK_DELETE
; break;
397 case GDK_Home
: key_code
= WXK_HOME
; break;
398 case GDK_Left
: key_code
= WXK_LEFT
; break;
399 case GDK_Up
: key_code
= WXK_UP
; break;
400 case GDK_Right
: key_code
= WXK_RIGHT
; break;
401 case GDK_Down
: key_code
= WXK_DOWN
; break;
402 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
403 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
404 case GDK_Next
: key_code
= WXK_NEXT
; break;
405 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
406 case GDK_End
: key_code
= WXK_END
; break;
407 case GDK_Begin
: key_code
= WXK_HOME
; break;
408 case GDK_Select
: key_code
= WXK_SELECT
; break;
409 case GDK_Print
: key_code
= WXK_PRINT
; break;
410 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
411 case GDK_Insert
: key_code
= WXK_INSERT
; break;
412 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
414 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
415 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
416 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
417 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
418 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
419 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
420 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
421 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
422 case GDK_KP_8
: key_code
= WXK_NUMPAD8
; break;
423 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
424 case GDK_KP_Space
: key_code
= WXK_NUMPAD_SPACE
; break;
425 case GDK_KP_Tab
: key_code
= WXK_NUMPAD_TAB
; break;
426 case GDK_KP_Enter
: key_code
= WXK_NUMPAD_ENTER
; break;
427 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
428 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
429 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
430 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
431 case GDK_KP_Home
: key_code
= WXK_NUMPAD_HOME
; break;
432 case GDK_KP_Left
: key_code
= WXK_NUMPAD_LEFT
; break;
433 case GDK_KP_Up
: key_code
= WXK_NUMPAD_UP
; break;
434 case GDK_KP_Right
: key_code
= WXK_NUMPAD_RIGHT
; break;
435 case GDK_KP_Down
: key_code
= WXK_NUMPAD_DOWN
; break;
436 case GDK_KP_Prior
: key_code
= WXK_NUMPAD_PRIOR
; break;
437 // case GDK_KP_Page_Up: key_code = WXK_NUMPAD_PAGEUP; break;
438 case GDK_KP_Next
: key_code
= WXK_NUMPAD_NEXT
; break;
439 // case GDK_KP_Page_Down: key_code = WXK_NUMPAD_PAGEDOWN; break;
440 case GDK_KP_End
: key_code
= WXK_NUMPAD_END
; break;
441 case GDK_KP_Begin
: key_code
= WXK_NUMPAD_BEGIN
; break;
442 case GDK_KP_Insert
: key_code
= WXK_NUMPAD_INSERT
; break;
443 case GDK_KP_Delete
: key_code
= WXK_NUMPAD_DELETE
; break;
444 case GDK_KP_Equal
: key_code
= WXK_NUMPAD_EQUAL
; break;
445 case GDK_KP_Multiply
: key_code
= WXK_NUMPAD_MULTIPLY
; break;
446 case GDK_KP_Add
: key_code
= WXK_NUMPAD_ADD
; break;
447 case GDK_KP_Separator
: key_code
= WXK_NUMPAD_SEPARATOR
; break;
448 case GDK_KP_Subtract
: key_code
= WXK_NUMPAD_SUBTRACT
; break;
449 case GDK_KP_Decimal
: key_code
= WXK_NUMPAD_DECIMAL
; break;
450 case GDK_KP_Divide
: key_code
= WXK_NUMPAD_DIVIDE
; break;
452 case GDK_F1
: key_code
= WXK_F1
; break;
453 case GDK_F2
: key_code
= WXK_F2
; break;
454 case GDK_F3
: key_code
= WXK_F3
; break;
455 case GDK_F4
: key_code
= WXK_F4
; break;
456 case GDK_F5
: key_code
= WXK_F5
; break;
457 case GDK_F6
: key_code
= WXK_F6
; break;
458 case GDK_F7
: key_code
= WXK_F7
; break;
459 case GDK_F8
: key_code
= WXK_F8
; break;
460 case GDK_F9
: key_code
= WXK_F9
; break;
461 case GDK_F10
: key_code
= WXK_F10
; break;
462 case GDK_F11
: key_code
= WXK_F11
; break;
463 case GDK_F12
: key_code
= WXK_F12
; break;
468 guint upper
= gdk_keyval_to_upper( (guint
)keysym
);
469 keysym
= (upper
!= 0 ? upper
: keysym
); /* to be MSW compatible */
470 key_code
= (guint
)keysym
;
478 static long map_to_wx_keysym( KeySym keysym
)
484 case GDK_Menu
: key_code
= WXK_MENU
; break;
485 case GDK_Help
: key_code
= WXK_HELP
; break;
486 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
487 case GDK_ISO_Left_Tab
:
488 case GDK_Tab
: key_code
= WXK_TAB
; break;
489 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
490 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
491 case GDK_Return
: key_code
= WXK_RETURN
; break;
492 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
493 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
494 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
495 case GDK_Delete
: key_code
= WXK_DELETE
; break;
496 case GDK_Home
: key_code
= WXK_HOME
; break;
497 case GDK_Left
: key_code
= WXK_LEFT
; break;
498 case GDK_Up
: key_code
= WXK_UP
; break;
499 case GDK_Right
: key_code
= WXK_RIGHT
; break;
500 case GDK_Down
: key_code
= WXK_DOWN
; break;
501 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
502 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
503 case GDK_Next
: key_code
= WXK_NEXT
; break;
504 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
505 case GDK_End
: key_code
= WXK_END
; break;
506 case GDK_Begin
: key_code
= WXK_HOME
; break;
507 case GDK_Select
: key_code
= WXK_SELECT
; break;
508 case GDK_Print
: key_code
= WXK_PRINT
; break;
509 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
510 case GDK_Insert
: key_code
= WXK_INSERT
; break;
511 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
513 case GDK_KP_0
: key_code
= '0'; break;
514 case GDK_KP_1
: key_code
= '1'; break;
515 case GDK_KP_2
: key_code
= '2'; break;
516 case GDK_KP_3
: key_code
= '3'; break;
517 case GDK_KP_4
: key_code
= '4'; break;
518 case GDK_KP_5
: key_code
= '5'; break;
519 case GDK_KP_6
: key_code
= '6'; break;
520 case GDK_KP_7
: key_code
= '7'; break;
521 case GDK_KP_8
: key_code
= '8'; break;
522 case GDK_KP_9
: key_code
= '9'; break;
523 case GDK_KP_Space
: key_code
= ' '; break;
524 case GDK_KP_Tab
: key_code
= WXK_TAB
; break; /* or '\t' ??? */
525 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break; /* or '\r' ??? */
526 case GDK_KP_F1
: key_code
= WXK_NUMPAD_F1
; break;
527 case GDK_KP_F2
: key_code
= WXK_NUMPAD_F2
; break;
528 case GDK_KP_F3
: key_code
= WXK_NUMPAD_F3
; break;
529 case GDK_KP_F4
: key_code
= WXK_NUMPAD_F4
; break;
530 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
531 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
532 case GDK_KP_Up
: key_code
= WXK_UP
; break;
533 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
534 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
535 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
536 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
537 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
538 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
539 case GDK_KP_End
: key_code
= WXK_END
; break;
540 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
541 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
542 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
543 case GDK_KP_Equal
: key_code
= '='; break;
544 case GDK_KP_Multiply
: key_code
= '*'; break;
545 case GDK_KP_Add
: key_code
= '+'; break;
546 case GDK_KP_Separator
: key_code
= ','; break;
547 case GDK_KP_Subtract
: key_code
= '-'; break;
548 case GDK_KP_Decimal
: key_code
= '.'; break;
549 case GDK_KP_Divide
: key_code
= '/'; break;
551 case GDK_F1
: key_code
= WXK_F1
; break;
552 case GDK_F2
: key_code
= WXK_F2
; break;
553 case GDK_F3
: key_code
= WXK_F3
; break;
554 case GDK_F4
: key_code
= WXK_F4
; break;
555 case GDK_F5
: key_code
= WXK_F5
; break;
556 case GDK_F6
: key_code
= WXK_F6
; break;
557 case GDK_F7
: key_code
= WXK_F7
; break;
558 case GDK_F8
: key_code
= WXK_F8
; break;
559 case GDK_F9
: key_code
= WXK_F9
; break;
560 case GDK_F10
: key_code
= WXK_F10
; break;
561 case GDK_F11
: key_code
= WXK_F11
; break;
562 case GDK_F12
: key_code
= WXK_F12
; break;
567 key_code
= (guint
)keysym
;
575 //-----------------------------------------------------------------------------
576 // "expose_event" of m_wxwindow
577 //-----------------------------------------------------------------------------
579 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
584 win
->GetUpdateRegion().Union( gdk_event
->area
.x
,
586 gdk_event
->area
.width
,
587 gdk_event
->area
.height
);
589 if (gdk_event
->count
> 0)
593 wxPrintf( "OnExpose from " );
594 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
595 wxPrintf( win->GetClassInfo()->GetClassName() );
596 wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x,
597 (int)gdk_event->area.y,
598 (int)gdk_event->area.width,
599 (int)gdk_event->area.height );
602 wxEraseEvent
eevent( win
->GetId() );
603 eevent
.SetEventObject( win
);
604 win
->GetEventHandler()->ProcessEvent(eevent
);
606 wxPaintEvent
event( win
->GetId() );
607 event
.SetEventObject( win
);
608 win
->GetEventHandler()->ProcessEvent( event
);
610 win
->GetUpdateRegion().Clear();
613 //-----------------------------------------------------------------------------
614 // "draw" of m_wxwindow
615 //-----------------------------------------------------------------------------
617 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
),
618 GdkRectangle
*rect
, wxWindow
*win
)
621 wxapp_install_idle_handler();
626 win
->GetUpdateRegion().Union( rect
->x
, rect
->y
,
627 rect
->width
, rect
->height
);
630 wxPrintf( "OnDraw from " );
631 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
632 printf( win->GetClassInfo()->GetClassName() );
633 wxPrintf( " %d %d %d %d\n", (int)rect->x,
639 wxEraseEvent
eevent( win
->GetId() );
640 eevent
.SetEventObject( win
);
641 win
->GetEventHandler()->ProcessEvent(eevent
);
643 wxPaintEvent
event( win
->GetId() );
644 event
.SetEventObject( win
);
645 win
->GetEventHandler()->ProcessEvent( event
);
647 win
->GetUpdateRegion().Clear();
650 //-----------------------------------------------------------------------------
651 // "key_press_event" from any window
652 //-----------------------------------------------------------------------------
654 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
657 wxapp_install_idle_handler();
659 if (!win
->m_hasVMT
) return FALSE
;
660 if (g_blockEventsOnDrag
) return FALSE
;
663 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
664 if (gdk_event->state & GDK_SHIFT_MASK)
665 printf( "ShiftDown.\n" );
667 printf( "ShiftUp.\n" );
668 if (gdk_event->state & GDK_CONTROL_MASK)
669 printf( "ControlDown.\n" );
671 printf( "ControlUp.\n" );
676 GdkModifierType state
;
677 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
681 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
682 /* sending unknown key events doesn't really make sense */
683 if (key_code
== 0) return FALSE
;
685 wxKeyEvent
event( wxEVT_KEY_DOWN
);
686 event
.SetTimestamp( gdk_event
->time
);
687 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
688 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
689 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
690 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
691 event
.m_keyCode
= key_code
;
692 event
.m_scanCode
= gdk_event
->keyval
;
695 event
.SetEventObject( win
);
696 ret
= win
->GetEventHandler()->ProcessEvent( event
);
701 wxWindow
*ancestor
= win
;
704 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
707 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
708 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
711 if (ancestor
->m_isFrame
)
713 ancestor
= ancestor
->GetParent();
716 #endif // wxUSE_ACCEL
718 /* wxMSW doesn't send char events with Alt pressed */
719 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
720 will only be sent if it is not in an accelerator table. */
721 key_code
= map_to_wx_keysym( gdk_event
->keyval
);
726 wxKeyEvent
event2( wxEVT_CHAR
);
727 event2
.SetTimestamp( gdk_event
->time
);
728 event2
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
729 event2
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
730 event2
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
731 event2
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
732 event2
.m_keyCode
= key_code
;
733 event2
.m_scanCode
= gdk_event
->keyval
;
736 event2
.SetEventObject( win
);
737 ret
= win
->GetEventHandler()->ProcessEvent( event2
);
740 /* win is a control: tab can be propagated up */
742 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
743 (!win
->HasFlag(wxTE_PROCESS_TAB
)) &&
744 (win
->GetParent()) &&
745 (win
->GetParent()->HasFlag( wxTAB_TRAVERSAL
)) )
747 wxNavigationKeyEvent new_event
;
748 new_event
.SetEventObject( win
);
749 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
750 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
751 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
752 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
753 new_event
.SetCurrentFocus( win
);
754 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
757 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
759 (gdk_event
->keyval
== GDK_Escape
) )
761 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
762 new_event
.SetEventObject( win
);
763 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
766 #if (GTK_MINOR_VERSION > 0)
767 /* Pressing F10 will activate the menu bar of the top frame. */
771 (gdk_event->keyval == GDK_F10) )
773 wxWindow *ancestor = win;
776 if (wxIsKindOf(ancestor,wxFrame))
778 wxFrame *frame = (wxFrame*) ancestor;
779 wxMenuBar *menubar = frame->GetMenuBar();
782 wxNode *node = menubar->GetMenus().First();
785 wxMenu *firstMenu = (wxMenu*) node->Data();
786 gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
792 ancestor = ancestor->GetParent();
799 Damn, I forgot why this didn't work, but it didn't work.
801 // win is a panel: up can be propagated to the panel
802 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
803 (gdk_event->keyval == GDK_Up))
805 win->m_parent->SetFocus();
809 // win is a panel: left/right can be propagated to the panel
810 if ((!ret) && (win->m_wxwindow) &&
811 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
812 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
814 wxNavigationKeyEvent new_event;
815 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
816 new_event.SetCurrentFocus( win );
817 ret = win->GetEventHandler()->ProcessEvent( new_event );
823 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
830 //-----------------------------------------------------------------------------
831 // "key_release_event" from any window
832 //-----------------------------------------------------------------------------
834 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
837 wxapp_install_idle_handler();
839 if (!win
->m_hasVMT
) return FALSE
;
840 if (g_blockEventsOnDrag
) return FALSE
;
843 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
844 if (gdk_event->state & GDK_SHIFT_MASK)
845 printf( "ShiftDown.\n" );
847 printf( "ShiftUp.\n" );
848 if (gdk_event->state & GDK_CONTROL_MASK)
849 printf( "ControlDown.\n" );
851 printf( "ControlUp.\n" );
855 long key_code
= map_to_unmodified_wx_keysym( gdk_event
->keyval
);
857 /* sending unknown key events doesn't really make sense */
858 if (key_code
== 0) return FALSE
;
862 GdkModifierType state
;
863 if (gdk_event
->window
) gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
865 wxKeyEvent
event( wxEVT_KEY_UP
);
866 event
.SetTimestamp( gdk_event
->time
);
867 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
868 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
869 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
870 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
871 event
.m_keyCode
= key_code
;
872 event
.m_scanCode
= gdk_event
->keyval
;
875 event
.SetEventObject( win
);
877 if (win
->GetEventHandler()->ProcessEvent( event
))
879 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
886 //-----------------------------------------------------------------------------
887 // "button_press_event"
888 //-----------------------------------------------------------------------------
890 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
893 wxapp_install_idle_handler();
896 wxPrintf( wxT("1) OnButtonPress from ") );
897 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
898 wxPrintf( win->GetClassInfo()->GetClassName() );
899 wxPrintf( wxT(".\n") );
901 if (!win
->m_hasVMT
) return FALSE
;
902 if (g_blockEventsOnDrag
) return TRUE
;
903 if (g_blockEventsOnScroll
) return TRUE
;
905 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
909 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
911 gtk_widget_grab_focus (win
->m_wxwindow
);
914 wxPrintf( wxT("GrabFocus from ") );
915 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
916 wxPrintf( win->GetClassInfo()->GetClassName() );
917 wxPrintf( wxT(".\n") );
923 wxEventType event_type
= wxEVT_LEFT_DOWN
;
925 if (gdk_event
->button
== 1)
927 switch (gdk_event
->type
)
929 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
930 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
934 else if (gdk_event
->button
== 2)
936 switch (gdk_event
->type
)
938 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
939 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
943 else if (gdk_event
->button
== 3)
945 switch (gdk_event
->type
)
947 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
948 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
953 wxMouseEvent
event( event_type
);
954 event
.SetTimestamp( gdk_event
->time
);
955 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
956 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
957 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
958 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
959 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
960 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
961 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
963 event
.m_x
= (long)gdk_event
->x
;
964 event
.m_y
= (long)gdk_event
->y
;
966 // Some control don't have their own X window and thus cannot get
969 if (!g_captureWindow
)
971 wxCoord x
= event
.m_x
;
972 wxCoord y
= event
.m_y
;
975 GtkPizza
*pizza
= GTK_PIZZA(win
->m_wxwindow
);
980 wxNode
*node
= win
->GetChildren().First();
983 wxWindow
*child
= (wxWindow
*)node
->Data();
986 if (!child
->IsShown())
989 if (child
->m_isStaticBox
)
991 // wxStaticBox is transparent in the box itself
992 int xx1
= child
->m_x
;
993 int yy1
= child
->m_y
;
994 int xx2
= child
->m_x
+ child
->m_width
;
995 int yy2
= child
->m_x
+ child
->m_height
;
998 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1000 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1002 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1004 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1007 event
.m_x
-= child
->m_x
;
1008 event
.m_y
-= child
->m_y
;
1015 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1016 (child
->m_x
<= x
) &&
1017 (child
->m_y
<= y
) &&
1018 (child
->m_x
+child
->m_width
>= x
) &&
1019 (child
->m_y
+child
->m_height
>= y
))
1022 event
.m_x
-= child
->m_x
;
1023 event
.m_y
-= child
->m_y
;
1030 event
.SetEventObject( win
);
1032 gs_timeLastClick
= gdk_event
->time
;
1035 wxPrintf( wxT("2) OnButtonPress from ") );
1036 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1037 wxPrintf( win->GetClassInfo()->GetClassName() );
1038 wxPrintf( wxT(".\n") );
1041 if (win
->GetEventHandler()->ProcessEvent( event
))
1043 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
1050 //-----------------------------------------------------------------------------
1051 // "button_release_event"
1052 //-----------------------------------------------------------------------------
1054 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
1057 wxapp_install_idle_handler();
1059 if (!win
->m_hasVMT
) return FALSE
;
1060 if (g_blockEventsOnDrag
) return FALSE
;
1061 if (g_blockEventsOnScroll
) return FALSE
;
1063 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1066 printf( "OnButtonRelease from " );
1067 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1068 printf( win->GetClassInfo()->GetClassName() );
1072 wxEventType event_type
= wxEVT_NULL
;
1074 switch (gdk_event
->button
)
1076 case 1: event_type
= wxEVT_LEFT_UP
; break;
1077 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
1078 case 3: event_type
= wxEVT_RIGHT_UP
; break;
1081 wxMouseEvent
event( event_type
);
1082 event
.SetTimestamp( gdk_event
->time
);
1083 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1084 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1085 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1086 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1087 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1088 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1089 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1090 event
.m_x
= (long)gdk_event
->x
;
1091 event
.m_y
= (long)gdk_event
->y
;
1093 // Some control don't have their own X window and thus cannot get
1096 if (!g_captureWindow
)
1098 wxCoord x
= event
.m_x
;
1099 wxCoord y
= event
.m_y
;
1100 if (win
->m_wxwindow
)
1102 GtkPizza
*pizza
= GTK_PIZZA(win
->m_wxwindow
);
1103 x
+= pizza
->xoffset
;
1104 y
+= pizza
->yoffset
;
1107 wxNode
*node
= win
->GetChildren().First();
1110 wxWindow
*child
= (wxWindow
*)node
->Data();
1112 node
= node
->Next();
1113 if (!child
->IsShown())
1116 if (child
->m_isStaticBox
)
1118 // wxStaticBox is transparent in the box itself
1119 int xx1
= child
->m_x
;
1120 int yy1
= child
->m_y
;
1121 int xx2
= child
->m_x
+ child
->m_width
;
1122 int yy2
= child
->m_x
+ child
->m_height
;
1125 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1127 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1129 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1131 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1134 event
.m_x
-= child
->m_x
;
1135 event
.m_y
-= child
->m_y
;
1142 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1143 (child
->m_x
<= x
) &&
1144 (child
->m_y
<= y
) &&
1145 (child
->m_x
+child
->m_width
>= x
) &&
1146 (child
->m_y
+child
->m_height
>= y
))
1149 event
.m_x
-= child
->m_x
;
1150 event
.m_y
-= child
->m_y
;
1157 event
.SetEventObject( win
);
1159 if (win
->GetEventHandler()->ProcessEvent( event
))
1161 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
1168 //-----------------------------------------------------------------------------
1169 // "motion_notify_event"
1170 //-----------------------------------------------------------------------------
1172 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
1175 wxapp_install_idle_handler();
1177 if (!win
->m_hasVMT
) return FALSE
;
1178 if (g_blockEventsOnDrag
) return FALSE
;
1179 if (g_blockEventsOnScroll
) return FALSE
;
1181 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1183 if (gdk_event
->is_hint
)
1187 GdkModifierType state
;
1188 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
1194 printf( "OnMotion from " );
1195 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1196 printf( win->GetClassInfo()->GetClassName() );
1200 wxMouseEvent
event( wxEVT_MOTION
);
1201 event
.SetTimestamp( gdk_event
->time
);
1202 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
1203 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
1204 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
1205 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
1206 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
1207 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
1208 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
1210 event
.m_x
= (long)gdk_event
->x
;
1211 event
.m_y
= (long)gdk_event
->y
;
1213 // Some control don't have their own X window and thus cannot get
1216 if (!g_captureWindow
)
1218 wxCoord x
= event
.m_x
;
1219 wxCoord y
= event
.m_y
;
1220 if (win
->m_wxwindow
)
1222 GtkPizza
*pizza
= GTK_PIZZA(win
->m_wxwindow
);
1223 x
+= pizza
->xoffset
;
1224 y
+= pizza
->yoffset
;
1227 wxNode
*node
= win
->GetChildren().First();
1230 wxWindow
*child
= (wxWindow
*)node
->Data();
1232 node
= node
->Next();
1233 if (!child
->IsShown())
1236 if (child
->m_isStaticBox
)
1238 // wxStaticBox is transparent in the box itself
1239 int xx1
= child
->m_x
;
1240 int yy1
= child
->m_y
;
1241 int xx2
= child
->m_x
+ child
->m_width
;
1242 int yy2
= child
->m_x
+ child
->m_height
;
1245 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
1247 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
1249 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
1251 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
1254 event
.m_x
-= child
->m_x
;
1255 event
.m_y
-= child
->m_y
;
1262 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
1263 (child
->m_x
<= x
) &&
1264 (child
->m_y
<= y
) &&
1265 (child
->m_x
+child
->m_width
>= x
) &&
1266 (child
->m_y
+child
->m_height
>= y
))
1269 event
.m_x
-= child
->m_x
;
1270 event
.m_y
-= child
->m_y
;
1277 event
.SetEventObject( win
);
1279 if (win
->GetEventHandler()->ProcessEvent( event
))
1281 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1288 //-----------------------------------------------------------------------------
1290 //-----------------------------------------------------------------------------
1292 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1295 wxapp_install_idle_handler();
1297 if (!win
->m_hasVMT
) return FALSE
;
1298 if (g_blockEventsOnDrag
) return FALSE
;
1300 g_focusWindow
= win
;
1303 printf( "OnSetFocus from " );
1304 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1305 printf( win->GetClassInfo()->GetClassName() );
1307 printf( WXSTRINGCAST win->GetLabel() );
1311 wxPanel
*panel
= wxDynamicCast(win
->GetParent(), wxPanel
);
1314 panel
->SetLastFocus(win
);
1317 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1318 event
.SetEventObject( win
);
1320 if (win
->GetEventHandler()->ProcessEvent( event
))
1322 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1329 //-----------------------------------------------------------------------------
1330 // "focus_out_event"
1331 //-----------------------------------------------------------------------------
1333 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1336 wxapp_install_idle_handler();
1338 if (!win
->m_hasVMT
) return FALSE
;
1339 if (g_blockEventsOnDrag
) return FALSE
;
1342 printf( "OnKillFocus from " );
1343 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1344 printf( win->GetClassInfo()->GetClassName() );
1348 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1349 event
.SetEventObject( win
);
1351 if (win
->GetEventHandler()->ProcessEvent( event
))
1353 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1360 //-----------------------------------------------------------------------------
1361 // "enter_notify_event"
1362 //-----------------------------------------------------------------------------
1364 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1367 wxapp_install_idle_handler();
1369 if (!win
->m_hasVMT
) return FALSE
;
1370 if (g_blockEventsOnDrag
) return FALSE
;
1372 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1374 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1375 #if (GTK_MINOR_VERSION > 0)
1376 event
.SetTimestamp( gdk_event
->time
);
1378 event
.SetEventObject( win
);
1382 GdkModifierType state
= (GdkModifierType
)0;
1384 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1386 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1387 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1388 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1389 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1390 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1391 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1392 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1394 event
.m_x
= (long)x
;
1395 event
.m_y
= (long)y
;
1397 if (win
->GetEventHandler()->ProcessEvent( event
))
1399 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1406 //-----------------------------------------------------------------------------
1407 // "leave_notify_event"
1408 //-----------------------------------------------------------------------------
1410 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1413 wxapp_install_idle_handler();
1415 if (!win
->m_hasVMT
) return FALSE
;
1416 if (g_blockEventsOnDrag
) return FALSE
;
1418 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1420 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1421 #if (GTK_MINOR_VERSION > 0)
1422 event
.SetTimestamp( gdk_event
->time
);
1424 event
.SetEventObject( win
);
1428 GdkModifierType state
= (GdkModifierType
)0;
1430 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1432 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1433 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1434 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1435 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1436 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1437 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1438 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1440 event
.m_x
= (long)x
;
1441 event
.m_y
= (long)y
;
1443 if (win
->GetEventHandler()->ProcessEvent( event
))
1445 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1452 //-----------------------------------------------------------------------------
1453 // "value_changed" from m_vAdjust
1454 //-----------------------------------------------------------------------------
1456 static void gtk_window_vscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1459 wxapp_install_idle_handler();
1461 if (g_blockEventsOnDrag
) return;
1463 if (!win
->m_hasVMT
) return;
1465 float diff
= adjust
->value
- win
->m_oldVerticalPos
;
1466 if (fabs(diff
) < 0.2) return;
1468 win
->m_oldVerticalPos
= adjust
->value
;
1470 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1471 GtkRange
*range
= GTK_RANGE( scrolledWindow
->vscrollbar
);
1473 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1474 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1475 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1476 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1477 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1479 int value
= (int)(adjust
->value
+0.5);
1481 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1482 event
.SetEventObject( win
);
1483 win
->GetEventHandler()->ProcessEvent( event
);
1486 //-----------------------------------------------------------------------------
1487 // "value_changed" from m_hAdjust
1488 //-----------------------------------------------------------------------------
1490 static void gtk_window_hscroll_callback( GtkAdjustment
*adjust
, wxWindow
*win
)
1493 wxapp_install_idle_handler();
1495 if (g_blockEventsOnDrag
) return;
1496 if (!win
->m_hasVMT
) return;
1498 float diff
= adjust
->value
- win
->m_oldHorizontalPos
;
1499 if (fabs(diff
) < 0.2) return;
1501 win
->m_oldHorizontalPos
= adjust
->value
;
1503 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1504 GtkRange
*range
= GTK_RANGE( scrolledWindow
->hscrollbar
);
1506 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1507 if (range
->scroll_type
== GTK_SCROLL_STEP_BACKWARD
) command
= wxEVT_SCROLLWIN_LINEUP
;
1508 else if (range
->scroll_type
== GTK_SCROLL_STEP_FORWARD
) command
= wxEVT_SCROLLWIN_LINEDOWN
;
1509 else if (range
->scroll_type
== GTK_SCROLL_PAGE_BACKWARD
) command
= wxEVT_SCROLLWIN_PAGEUP
;
1510 else if (range
->scroll_type
== GTK_SCROLL_PAGE_FORWARD
) command
= wxEVT_SCROLLWIN_PAGEDOWN
;
1512 int value
= (int)(adjust
->value
+0.5);
1514 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1515 event
.SetEventObject( win
);
1516 win
->GetEventHandler()->ProcessEvent( event
);
1519 //-----------------------------------------------------------------------------
1520 // "changed" from m_vAdjust
1521 //-----------------------------------------------------------------------------
1523 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1526 wxapp_install_idle_handler();
1528 if (g_blockEventsOnDrag
) return;
1529 if (!win
->m_hasVMT
) return;
1531 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1532 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1534 wxScrollWinEvent
event( command
, value
, wxVERTICAL
);
1535 event
.SetEventObject( win
);
1536 win
->GetEventHandler()->ProcessEvent( event
);
1539 //-----------------------------------------------------------------------------
1540 // "changed" from m_hAdjust
1541 //-----------------------------------------------------------------------------
1543 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1546 wxapp_install_idle_handler();
1548 if (g_blockEventsOnDrag
) return;
1549 if (!win
->m_hasVMT
) return;
1551 wxEventType command
= wxEVT_SCROLLWIN_THUMBTRACK
;
1552 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1554 wxScrollWinEvent
event( command
, value
, wxHORIZONTAL
);
1555 event
.SetEventObject( win
);
1556 win
->GetEventHandler()->ProcessEvent( event
);
1559 //-----------------------------------------------------------------------------
1560 // "button_press_event" from scrollbar
1561 //-----------------------------------------------------------------------------
1563 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1564 GdkEventButton
*WXUNUSED(gdk_event
),
1568 wxapp_install_idle_handler();
1570 // don't test here as we can release the mouse while being over
1571 // a different window than the slider
1573 // if (gdk_event->window != widget->slider) return FALSE;
1575 win
->SetScrolling( TRUE
);
1580 //-----------------------------------------------------------------------------
1581 // "button_release_event" from scrollbar
1582 //-----------------------------------------------------------------------------
1584 static gint
gtk_scrollbar_button_release_callback( GtkRange
*WXUNUSED(widget
),
1585 GdkEventButton
*WXUNUSED(gdk_event
),
1589 // don't test here as we can release the mouse while being over
1590 // a different window than the slider
1592 // if (gdk_event->window != widget->slider) return FALSE;
1594 win
->SetScrolling( FALSE
);
1599 // ----------------------------------------------------------------------------
1600 // this wxWindowBase function is implemented here (in platform-specific file)
1601 // because it is static and so couldn't be made virtual
1602 // ----------------------------------------------------------------------------
1604 wxWindow
*wxWindowBase::FindFocus()
1606 return g_focusWindow
;
1609 //-----------------------------------------------------------------------------
1610 // "realize" from m_widget
1611 //-----------------------------------------------------------------------------
1613 /* we cannot set colours and fonts before the widget has
1614 been realized, so we do this directly after realization */
1617 gtk_window_realized_callback( GtkWidget
* WXUNUSED(widget
), wxWindow
*win
)
1620 wxapp_install_idle_handler();
1622 if (win
->m_delayedFont
)
1623 win
->SetFont( win
->GetFont() );
1625 if (win
->m_delayedBackgroundColour
)
1626 win
->SetBackgroundColour( win
->GetBackgroundColour() );
1628 if (win
->m_delayedForegroundColour
)
1629 win
->SetForegroundColour( win
->GetForegroundColour() );
1631 wxWindowCreateEvent
event( win
);
1632 event
.SetEventObject( win
);
1633 win
->GetEventHandler()->ProcessEvent( event
);
1638 //-----------------------------------------------------------------------------
1639 // InsertChild for wxWindow.
1640 //-----------------------------------------------------------------------------
1642 /* Callback for wxWindow. This very strange beast has to be used because
1643 * C++ has no virtual methods in a constructor. We have to emulate a
1644 * virtual function here as wxNotebook requires a different way to insert
1645 * a child in it. I had opted for creating a wxNotebookPage window class
1646 * which would have made this superfluous (such in the MDI window system),
1647 * but no-one was listening to me... */
1649 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1651 /* the window might have been scrolled already, do we
1652 have to adapt the position */
1653 GtkPizza
*pizza
= GTK_PIZZA(parent
->m_wxwindow
);
1654 child
->m_x
+= pizza
->xoffset
;
1655 child
->m_y
+= pizza
->yoffset
;
1657 gtk_pizza_put( GTK_PIZZA(parent
->m_wxwindow
),
1658 GTK_WIDGET(child
->m_widget
),
1665 //-----------------------------------------------------------------------------
1667 //-----------------------------------------------------------------------------
1669 wxWindow
* wxGetActiveWindow()
1671 return g_focusWindow
;
1674 //-----------------------------------------------------------------------------
1676 //-----------------------------------------------------------------------------
1678 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
1680 void wxWindow::Init()
1686 m_widget
= (GtkWidget
*) NULL
;
1687 m_wxwindow
= (GtkWidget
*) NULL
;
1697 m_needParent
= TRUE
;
1698 m_isBeingDeleted
= FALSE
;
1701 m_nativeSizeEvent
= FALSE
;
1703 m_hasScrolling
= FALSE
;
1704 m_isScrolling
= FALSE
;
1706 m_hAdjust
= (GtkAdjustment
*) NULL
;
1707 m_vAdjust
= (GtkAdjustment
*) NULL
;
1708 m_oldHorizontalPos
= 0.0;
1709 m_oldVerticalPos
= 0.0;
1712 m_widgetStyle
= (GtkStyle
*) NULL
;
1714 m_insertCallback
= (wxInsertChildFunction
) NULL
;
1716 m_isStaticBox
= FALSE
;
1717 m_isRadioButton
= FALSE
;
1719 m_acceptsFocus
= FALSE
;
1721 m_cursor
= *wxSTANDARD_CURSOR
;
1724 wxWindow::wxWindow()
1729 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1730 const wxPoint
&pos
, const wxSize
&size
,
1731 long style
, const wxString
&name
)
1735 Create( parent
, id
, pos
, size
, style
, name
);
1738 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1739 const wxPoint
&pos
, const wxSize
&size
,
1740 long style
, const wxString
&name
)
1742 if (!PreCreation( parent
, pos
, size
) ||
1743 !CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
))
1745 wxFAIL_MSG( wxT("wxWindow creation failed") );
1749 m_insertCallback
= wxInsertChildInWindow
;
1751 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1752 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1755 debug_focus_in( m_widget
, wxT("wxWindow::m_widget"), name
);
1758 GtkScrolledWindow
*scrolledWindow
= GTK_SCROLLED_WINDOW(m_widget
);
1761 debug_focus_in( scrolledWindow
->hscrollbar
, wxT("wxWindow::hsrcollbar"), name
);
1762 debug_focus_in( scrolledWindow
->vscrollbar
, wxT("wxWindow::vsrcollbar"), name
);
1765 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1766 scroll_class
->scrollbar_spacing
= 0;
1768 gtk_scrolled_window_set_policy( scrolledWindow
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1770 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->hscrollbar
) );
1771 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(scrolledWindow
->vscrollbar
) );
1773 m_wxwindow
= gtk_pizza_new();
1776 debug_focus_in( m_wxwindow
, wxT("wxWindow::m_wxwindow"), name
);
1779 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1781 #if (GTK_MINOR_VERSION > 0)
1782 GtkPizza
*pizza
= GTK_PIZZA(m_wxwindow
);
1784 if (HasFlag(wxRAISED_BORDER
))
1786 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_OUT
);
1788 else if (HasFlag(wxSUNKEN_BORDER
))
1790 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_IN
);
1792 else if (HasFlag(wxSIMPLE_BORDER
))
1794 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_THIN
);
1798 gtk_pizza_set_shadow_type( pizza
, GTK_MYSHADOW_NONE
);
1800 #else // GTK_MINOR_VERSION == 0
1801 GtkViewport
*viewport
= GTK_VIEWPORT(scrolledWindow
->viewport
);
1803 if (HasFlag(wxRAISED_BORDER
))
1805 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1807 else if (HasFlag(wxSUNKEN_BORDER
))
1809 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1813 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1815 #endif // GTK_MINOR_VERSION
1817 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1818 m_acceptsFocus
= TRUE
;
1820 #if (GTK_MINOR_VERSION == 0)
1821 // shut the viewport up
1822 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1823 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1824 #endif // GTK_MINOR_VERSION == 0
1826 // I _really_ don't want scrollbars in the beginning
1827 m_vAdjust
->lower
= 0.0;
1828 m_vAdjust
->upper
= 1.0;
1829 m_vAdjust
->value
= 0.0;
1830 m_vAdjust
->step_increment
= 1.0;
1831 m_vAdjust
->page_increment
= 1.0;
1832 m_vAdjust
->page_size
= 5.0;
1833 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1834 m_hAdjust
->lower
= 0.0;
1835 m_hAdjust
->upper
= 1.0;
1836 m_hAdjust
->value
= 0.0;
1837 m_hAdjust
->step_increment
= 1.0;
1838 m_hAdjust
->page_increment
= 1.0;
1839 m_hAdjust
->page_size
= 5.0;
1840 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1842 // these handlers block mouse events to any window during scrolling such as
1843 // motion events and prevent GTK and wxWindows from fighting over where the
1846 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_press_event",
1847 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1849 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_press_event",
1850 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1852 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->vscrollbar
), "button_release_event",
1853 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1855 gtk_signal_connect( GTK_OBJECT(scrolledWindow
->hscrollbar
), "button_release_event",
1856 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1858 // these handlers get notified when screen updates are required either when
1859 // scrolling or when the window size (and therefore scrollbar configuration)
1862 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1863 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1864 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1865 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1867 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1868 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1869 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1870 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1872 gtk_widget_show( m_wxwindow
);
1875 m_parent
->DoAddChild( this );
1884 wxWindow::~wxWindow()
1886 m_isBeingDeleted
= TRUE
;
1895 m_parent
->RemoveChild( this );
1899 gtk_style_unref( m_widgetStyle
);
1900 m_widgetStyle
= (GtkStyle
*) NULL
;
1905 gtk_widget_destroy( m_wxwindow
);
1906 m_wxwindow
= (GtkWidget
*) NULL
;
1911 gtk_widget_destroy( m_widget
);
1912 m_widget
= (GtkWidget
*) NULL
;
1916 bool wxWindow::PreCreation( wxWindow
*parent
, const wxPoint
&pos
, const wxSize
&size
)
1918 wxCHECK_MSG( !m_needParent
|| parent
, FALSE
, wxT("Need complete parent.") );
1920 /* this turns -1 into 20 so that a minimal window is
1921 visible even although -1,-1 has been given as the
1922 size of the window. the same trick is used in other
1923 ports and should make debugging easier */
1924 m_width
= WidthDefault(size
.x
);
1925 m_height
= HeightDefault(size
.y
);
1930 /* some reasonable defaults */
1935 m_x
= (gdk_screen_width () - m_width
) / 2;
1936 if (m_x
< 10) m_x
= 10;
1940 m_y
= (gdk_screen_height () - m_height
) / 2;
1941 if (m_y
< 10) m_y
= 10;
1948 void wxWindow::PostCreation()
1950 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
1956 /* these get reported to wxWindows -> wxPaintEvent */
1957 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1958 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1960 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1961 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1964 #if (GTK_MINOR_VERSION > 0)
1965 /* these are called when the "sunken" or "raised" borders are drawn */
1966 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1967 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1969 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1970 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1974 GtkWidget
*connect_widget
= GetConnectWidget();
1976 ConnectWidget( connect_widget
);
1978 /* we cannot set colours, fonts and cursors before the widget has
1979 been realized, so we do this directly after realization */
1980 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1981 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1986 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1988 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1989 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1991 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1992 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1994 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1995 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1997 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1998 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
2000 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
2001 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
2003 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
2004 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
2006 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
2007 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
2009 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
2010 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
2012 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
2013 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
2016 bool wxWindow::Destroy()
2018 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2022 return wxWindowBase::Destroy();
2025 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
2027 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2028 wxASSERT_MSG( (m_parent
!= NULL
), wxT("wxWindow::SetSize requires parent.\n") );
2030 if (m_resizing
) return; /* I don't like recursions */
2033 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
2035 /* don't set the size for children of wxNotebook, just take the values. */
2043 GtkPizza
*pizza
= GTK_PIZZA(m_parent
->m_wxwindow
);
2045 if ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0)
2047 if (x
!= -1) m_x
= x
+ pizza
->xoffset
;
2048 if (y
!= -1) m_y
= y
+ pizza
->yoffset
;
2049 if (width
!= -1) m_width
= width
;
2050 if (height
!= -1) m_height
= height
;
2054 m_x
= x
+ pizza
->xoffset
;
2055 m_y
= y
+ pizza
->yoffset
;
2060 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2062 if (width
== -1) m_width
= 80;
2065 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2067 if (height
== -1) m_height
= 26;
2070 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2071 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2072 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2073 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2076 int bottom_border
= 0;
2078 if (GTK_WIDGET_CAN_DEFAULT(m_widget
))
2080 /* the default button has a border around it */
2085 gtk_pizza_set_size( GTK_PIZZA(m_parent
->m_wxwindow
),
2090 m_height
+border
+bottom_border
);
2094 wxPrintf( "OnSize sent from " );
2095 if (GetClassInfo() && GetClassInfo()->GetClassName())
2096 wxPrintf( GetClassInfo()->GetClassName() );
2097 wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height );
2100 if (!m_nativeSizeEvent
)
2102 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2103 event
.SetEventObject( this );
2104 GetEventHandler()->ProcessEvent( event
);
2110 void wxWindow::OnInternalIdle()
2112 wxCursor cursor
= m_cursor
;
2113 if (g_globalCursor
.Ok()) cursor
= g_globalCursor
;
2117 /* I now set the cursor anew in every OnInternalIdle call
2118 as setting the cursor in a parent window also effects the
2119 windows above so that checking for the current cursor is
2124 GdkWindow
*window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2126 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2128 if (!g_globalCursor
.Ok())
2129 cursor
= *wxSTANDARD_CURSOR
;
2131 window
= m_widget
->window
;
2132 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2133 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2139 GdkWindow
*window
= m_widget
->window
;
2140 if ((window
) && !(GTK_WIDGET_NO_WINDOW(m_widget
)))
2141 gdk_window_set_cursor( window
, cursor
.GetCursor() );
2149 void wxWindow::DoGetSize( int *width
, int *height
) const
2151 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2153 if (width
) (*width
) = m_width
;
2154 if (height
) (*height
) = m_height
;
2157 void wxWindow::DoSetClientSize( int width
, int height
)
2159 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2163 SetSize( width
, height
);
2170 #if (GTK_MINOR_VERSION == 0)
2171 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2175 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2176 #if 0 // unused - if this is ok, just remove this line (VZ)
2177 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2180 GtkWidget
*viewport
= scroll_window
->viewport
;
2181 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2183 dw
+= 2 * viewport_class
->xthickness
;
2184 dh
+= 2 * viewport_class
->ythickness
;
2188 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2190 /* when using GTK 1.2 we set the shadow border size to 2 */
2194 if (HasFlag(wxSIMPLE_BORDER
))
2196 /* when using GTK 1.2 we set the simple border size to 1 */
2205 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2206 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2208 we use this instead: range.slider_width = 11 + 2*2pts edge
2211 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2212 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2214 if (scroll_window
->vscrollbar_visible
)
2216 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2217 dw
+= scroll_class
->scrollbar_spacing
;
2220 if (scroll_window
->hscrollbar_visible
)
2222 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2223 dh
+= scroll_class
->scrollbar_spacing
;
2227 SetSize( width
+dw
, height
+dh
);
2231 void wxWindow::DoGetClientSize( int *width
, int *height
) const
2233 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2237 if (width
) (*width
) = m_width
;
2238 if (height
) (*height
) = m_height
;
2245 #if (GTK_MINOR_VERSION == 0)
2246 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2250 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2251 #if 0 // unused - if this is ok, just remove this line (VZ)
2252 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2255 GtkWidget
*viewport
= scroll_window
->viewport
;
2256 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2258 dw
+= 2 * viewport_class
->xthickness
;
2259 dh
+= 2 * viewport_class
->ythickness
;
2263 if (HasFlag(wxRAISED_BORDER
) || HasFlag(wxSUNKEN_BORDER
))
2265 /* when using GTK 1.2 we set the shadow border size to 2 */
2269 if (HasFlag(wxSIMPLE_BORDER
))
2271 /* when using GTK 1.2 we set the simple border size to 1 */
2279 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2280 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2282 we use this instead: range.slider_width = 11 + 2*2pts edge
2285 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2286 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2288 if (scroll_window
->vscrollbar_visible
)
2290 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2291 dw
+= scroll_class
->scrollbar_spacing
;
2294 if (scroll_window
->hscrollbar_visible
)
2296 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2297 dh
+= scroll_class
->scrollbar_spacing
;
2301 if (width
) (*width
) = m_width
- dw
;
2302 if (height
) (*height
) = m_height
- dh
;
2306 void wxWindow::DoGetPosition( int *x
, int *y
) const
2308 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2312 if (m_parent
&& m_parent
->m_wxwindow
)
2314 GtkPizza
*pizza
= GTK_PIZZA(m_parent
->m_wxwindow
);
2315 dx
= pizza
->xoffset
;
2316 dy
= pizza
->yoffset
;
2319 if (x
) (*x
) = m_x
- dx
;
2320 if (y
) (*y
) = m_y
- dy
;
2323 void wxWindow::DoClientToScreen( int *x
, int *y
) const
2325 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2327 if (!m_widget
->window
) return;
2329 GdkWindow
*source
= (GdkWindow
*) NULL
;
2331 source
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2333 source
= m_widget
->window
;
2337 gdk_window_get_origin( source
, &org_x
, &org_y
);
2341 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2343 org_x
+= m_widget
->allocation
.x
;
2344 org_y
+= m_widget
->allocation
.y
;
2352 void wxWindow::DoScreenToClient( int *x
, int *y
) const
2354 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2356 if (!m_widget
->window
) return;
2358 GdkWindow
*source
= (GdkWindow
*) NULL
;
2360 source
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2362 source
= m_widget
->window
;
2366 gdk_window_get_origin( source
, &org_x
, &org_y
);
2370 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2372 org_x
+= m_widget
->allocation
.x
;
2373 org_y
+= m_widget
->allocation
.y
;
2381 bool wxWindow::Show( bool show
)
2383 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2385 if (!wxWindowBase::Show(show
))
2392 gtk_widget_show( m_widget
);
2394 gtk_widget_hide( m_widget
);
2399 bool wxWindow::Enable( bool enable
)
2401 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2403 if (!wxWindowBase::Enable(enable
))
2409 gtk_widget_set_sensitive( m_widget
, enable
);
2411 gtk_widget_set_sensitive( m_wxwindow
, enable
);
2416 int wxWindow::GetCharHeight() const
2418 wxCHECK_MSG( (m_widget
!= NULL
), 12, wxT("invalid window") );
2420 wxCHECK_MSG( m_font
.Ok(), 12, wxT("invalid font") );
2422 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2424 return font
->ascent
+ font
->descent
;
2427 int wxWindow::GetCharWidth() const
2429 wxCHECK_MSG( (m_widget
!= NULL
), 8, wxT("invalid window") );
2431 wxCHECK_MSG( m_font
.Ok(), 8, wxT("invalid font") );
2433 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2435 return gdk_string_width( font
, "H" );
2438 void wxWindow::GetTextExtent( const wxString
& string
,
2442 int *externalLeading
,
2443 const wxFont
*theFont
) const
2445 wxFont fontToUse
= m_font
;
2446 if (theFont
) fontToUse
= *theFont
;
2448 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
2450 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2451 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2452 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2453 if (descent
) (*descent
) = font
->descent
;
2454 if (externalLeading
) (*externalLeading
) = 0; // ??
2457 void wxWindow::SetFocus()
2459 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2463 if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow
))
2464 gtk_widget_grab_focus (m_wxwindow
);
2470 if (GTK_WIDGET_CAN_FOCUS(m_widget
) && !GTK_WIDGET_HAS_FOCUS (m_widget
) )
2472 gtk_widget_grab_focus (m_widget
);
2474 else if (GTK_IS_CONTAINER(m_widget
))
2476 gtk_container_focus( GTK_CONTAINER(m_widget
), GTK_DIR_TAB_FORWARD
);
2485 bool wxWindow::AcceptsFocus() const
2487 return m_acceptsFocus
&& wxWindowBase::AcceptsFocus();
2490 bool wxWindow::Reparent( wxWindowBase
*newParentBase
)
2492 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2494 wxWindow
*oldParent
= m_parent
,
2495 *newParent
= (wxWindow
*)newParentBase
;
2497 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2499 if ( !wxWindowBase::Reparent(newParent
) )
2502 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2504 /* prevent GTK from deleting the widget arbitrarily */
2505 gtk_widget_ref( m_widget
);
2509 gtk_container_remove( GTK_CONTAINER(m_widget
->parent
), m_widget
);
2512 wxASSERT( GTK_IS_WIDGET(m_widget
) );
2516 /* insert GTK representation */
2517 (*(newParent
->m_insertCallback
))(newParent
, this);
2520 /* reverse: prevent GTK from deleting the widget arbitrarily */
2521 gtk_widget_unref( m_widget
);
2526 void wxWindow::DoAddChild(wxWindow
*child
)
2528 wxASSERT_MSG( (m_widget
!= NULL
), wxT("invalid window") );
2530 wxASSERT_MSG( (child
!= NULL
), wxT("invalid child window") );
2532 wxASSERT_MSG( (m_insertCallback
!= NULL
), wxT("invalid child insertion function") );
2537 /* insert GTK representation */
2538 (*m_insertCallback
)(this, child
);
2541 void wxWindow::Raise()
2543 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2545 if (!m_widget
->window
) return;
2547 gdk_window_raise( m_widget
->window
);
2550 void wxWindow::Lower()
2552 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2554 if (!m_widget
->window
) return;
2556 gdk_window_lower( m_widget
->window
);
2559 bool wxWindow::SetCursor( const wxCursor
&cursor
)
2561 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, wxT("invalid window") );
2563 return wxWindowBase::SetCursor( cursor
);
2566 void wxWindow::WarpPointer( int x
, int y
)
2568 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2570 /* we provide this function ourselves as it is
2571 missing in GDK (top of this file) */
2573 GdkWindow
*window
= (GdkWindow
*) NULL
;
2575 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2577 window
= GetConnectWidget()->window
;
2580 gdk_window_warp_pointer( window
, x
, y
);
2583 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2585 wxCHECK_RET( (m_widget
!= NULL
), wxT("invalid window") );
2587 if (!m_widget
->window
) return;
2589 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2593 gdk_window_clear_area( GTK_PIZZA(m_wxwindow
)->bin_window
,
2595 rect
->width
, rect
->height
);
2599 gdk_window_clear( GTK_PIZZA(m_wxwindow
)->bin_window
);
2603 /* there is no GTK equivalent of "draw only, don't clear" so we
2604 invent our own in the GtkPizza widget */
2610 GtkPizza
*pizza
= GTK_PIZZA(m_wxwindow
);
2611 gboolean old_clear
= pizza
->clear_on_draw
;
2612 gtk_pizza_set_clear( pizza
, FALSE
);
2614 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2616 gtk_pizza_set_clear( pizza
, old_clear
);
2619 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2623 GdkRectangle gdk_rect
;
2624 gdk_rect
.x
= rect
->x
;
2625 gdk_rect
.y
= rect
->y
;
2626 gdk_rect
.width
= rect
->width
;
2627 gdk_rect
.height
= rect
->height
;
2631 GtkPizza
*pizza
= GTK_PIZZA(m_wxwindow
);
2632 gboolean old_clear
= pizza
->clear_on_draw
;
2633 gtk_pizza_set_clear( pizza
, FALSE
);
2635 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2637 gtk_pizza_set_clear( pizza
, old_clear
);
2640 gtk_widget_draw( m_widget
, &gdk_rect
);
2644 void wxWindow::Clear()
2646 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2648 if (!m_widget
->window
) return;
2650 if (m_wxwindow
&& m_wxwindow
->window
)
2652 gdk_window_clear( m_wxwindow
->window
);
2657 void wxWindow::DoSetToolTip( wxToolTip
*tip
)
2659 wxWindowBase::DoSetToolTip(tip
);
2662 m_tooltip
->Apply( this );
2665 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2667 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConvCurrent
->cWX2MB(tip
), (gchar
*) NULL
);
2669 #endif // wxUSE_TOOLTIPS
2671 bool wxWindow::SetBackgroundColour( const wxColour
&colour
)
2673 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2675 if (!wxWindowBase::SetBackgroundColour(colour
))
2677 // don't leave if the GTK widget has just
2679 if (!m_delayedBackgroundColour
) return FALSE
;
2682 GdkWindow
*window
= (GdkWindow
*) NULL
;
2684 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2686 window
= GetConnectWidget()->window
;
2690 // indicate that a new style has been set
2691 // but it couldn't get applied as the
2692 // widget hasn't been realized yet.
2693 m_delayedBackgroundColour
= TRUE
;
2695 // pretend we have done something
2701 /* wxMSW doesn't clear the window here. I don't do that either to
2702 provide compatibility. call Clear() to do the job. */
2704 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2705 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2708 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2709 if (sysbg
== m_backgroundColour
)
2711 m_backgroundColour
= wxNullColour
;
2713 m_backgroundColour
= sysbg
;
2723 bool wxWindow::SetForegroundColour( const wxColour
&colour
)
2725 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2727 if (!wxWindowBase::SetForegroundColour(colour
))
2729 // don't leave if the GTK widget has just
2731 if (!m_delayedForegroundColour
) return FALSE
;
2734 GdkWindow
*window
= (GdkWindow
*) NULL
;
2736 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2738 window
= GetConnectWidget()->window
;
2742 // indicate that a new style has been set
2743 // but it couldn't get applied as the
2744 // widget hasn't been realized yet.
2745 m_delayedForegroundColour
= TRUE
;
2747 // pretend we have done something
2751 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2752 if ( sysbg
== m_backgroundColour
)
2754 m_backgroundColour
= wxNullColour
;
2756 m_backgroundColour
= sysbg
;
2766 GtkStyle
*wxWindow::GetWidgetStyle()
2768 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2770 m_widgetStyle
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
2772 return m_widgetStyle
;
2775 void wxWindow::SetWidgetStyle()
2777 GtkStyle
*style
= GetWidgetStyle();
2779 gdk_font_unref( style
->font
);
2780 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2782 if (m_foregroundColour
.Ok())
2784 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2785 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2786 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2787 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2790 if (m_backgroundColour
.Ok())
2792 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2793 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2794 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2795 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2796 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2797 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2798 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2799 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2800 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2804 void wxWindow::ApplyWidgetStyle()
2808 //-----------------------------------------------------------------------------
2809 // Pop-up menu stuff
2810 //-----------------------------------------------------------------------------
2812 static void gtk_pop_hide_callback( GtkWidget
*WXUNUSED(widget
), bool* is_waiting
)
2814 *is_waiting
= FALSE
;
2817 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2819 menu
->SetInvokingWindow( win
);
2820 wxMenuItemList::Node
*node
= menu
->GetMenuItems().GetFirst();
2823 wxMenuItem
*menuitem
= node
->GetData();
2824 if (menuitem
->IsSubMenu())
2826 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2829 node
= node
->GetNext();
2833 static gint gs_pop_x
= 0;
2834 static gint gs_pop_y
= 0;
2836 static void pop_pos_callback( GtkMenu
* WXUNUSED(menu
),
2840 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2845 bool wxWindow::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
2847 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2849 wxCHECK_MSG( menu
!= NULL
, FALSE
, wxT("invalid popup-menu") );
2851 SetInvokingWindow( menu
, this );
2858 bool is_waiting
= TRUE
;
2860 gtk_signal_connect( GTK_OBJECT(menu
->m_menu
), "hide",
2861 GTK_SIGNAL_FUNC(gtk_pop_hide_callback
), (gpointer
)&is_waiting
);
2864 GTK_MENU(menu
->m_menu
),
2865 (GtkWidget
*) NULL
, // parent menu shell
2866 (GtkWidget
*) NULL
, // parent menu item
2867 (GtkMenuPositionFunc
) pop_pos_callback
,
2868 (gpointer
) this, // client data
2869 0, // button used to activate it
2870 gs_timeLastClick
// the time of activation
2875 while (gtk_events_pending())
2876 gtk_main_iteration();
2882 #if wxUSE_DRAG_AND_DROP
2884 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2886 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2888 GtkWidget
*dnd_widget
= GetConnectWidget();
2890 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2892 if (m_dropTarget
) delete m_dropTarget
;
2893 m_dropTarget
= dropTarget
;
2895 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2898 #endif // wxUSE_DRAG_AND_DROP
2900 GtkWidget
* wxWindow::GetConnectWidget()
2902 GtkWidget
*connect_widget
= m_widget
;
2903 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2905 return connect_widget
;
2908 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2911 return (window
== GTK_PIZZA(m_wxwindow
)->bin_window
);
2913 return (window
== m_widget
->window
);
2916 bool wxWindow::SetFont( const wxFont
&font
)
2918 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, wxT("invalid window") );
2920 if (!wxWindowBase::SetFont(font
))
2922 // don't leave if the GTK widget has just
2924 if (!m_delayedFont
) return FALSE
;
2927 GdkWindow
*window
= (GdkWindow
*) NULL
;
2929 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2931 window
= GetConnectWidget()->window
;
2935 // indicate that a new style has been set
2936 // but it couldn't get applied as the
2937 // widget hasn't been realized yet.
2938 m_delayedFont
= TRUE
;
2940 // pretend we have done something
2944 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2945 if ( sysbg
== m_backgroundColour
)
2947 m_backgroundColour
= wxNullColour
;
2949 m_backgroundColour
= sysbg
;
2959 void wxWindow::CaptureMouse()
2961 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2963 wxCHECK_RET( g_captureWindow
== NULL
, wxT("CaptureMouse called twice") );
2965 GdkWindow
*window
= (GdkWindow
*) NULL
;
2967 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2969 window
= GetConnectWidget()->window
;
2971 if (!window
) return;
2973 gdk_pointer_grab( window
, FALSE
,
2975 (GDK_BUTTON_PRESS_MASK
|
2976 GDK_BUTTON_RELEASE_MASK
|
2977 GDK_POINTER_MOTION_HINT_MASK
|
2978 GDK_POINTER_MOTION_MASK
),
2980 m_cursor
.GetCursor(),
2981 (guint32
)GDK_CURRENT_TIME
);
2982 g_captureWindow
= this;
2985 void wxWindow::ReleaseMouse()
2987 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
2989 wxCHECK_RET( g_captureWindow
, wxT("ReleaseMouse called twice") );
2991 GdkWindow
*window
= (GdkWindow
*) NULL
;
2993 window
= GTK_PIZZA(m_wxwindow
)->bin_window
;
2995 window
= GetConnectWidget()->window
;
3000 gdk_pointer_ungrab ( (guint32
)GDK_CURRENT_TIME
);
3001 g_captureWindow
= (wxWindow
*) NULL
;
3004 bool wxWindow::IsRetained() const
3009 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3010 int range
, bool refresh
)
3012 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3014 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3016 m_hasScrolling
= TRUE
;
3018 if (orient
== wxHORIZONTAL
)
3020 float fpos
= (float)pos
;
3021 float frange
= (float)range
;
3022 float fthumb
= (float)thumbVisible
;
3023 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3024 if (fpos
< 0.0) fpos
= 0.0;
3026 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3027 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3029 SetScrollPos( orient
, pos
, refresh
);
3033 m_oldHorizontalPos
= fpos
;
3035 m_hAdjust
->lower
= 0.0;
3036 m_hAdjust
->upper
= frange
;
3037 m_hAdjust
->value
= fpos
;
3038 m_hAdjust
->step_increment
= 1.0;
3039 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3040 m_hAdjust
->page_size
= fthumb
;
3044 float fpos
= (float)pos
;
3045 float frange
= (float)range
;
3046 float fthumb
= (float)thumbVisible
;
3047 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3048 if (fpos
< 0.0) fpos
= 0.0;
3050 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3051 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3053 SetScrollPos( orient
, pos
, refresh
);
3057 m_oldVerticalPos
= fpos
;
3059 m_vAdjust
->lower
= 0.0;
3060 m_vAdjust
->upper
= frange
;
3061 m_vAdjust
->value
= fpos
;
3062 m_vAdjust
->step_increment
= 1.0;
3063 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3064 m_vAdjust
->page_size
= fthumb
;
3067 if (orient
== wxHORIZONTAL
)
3068 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3070 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3073 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3075 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3077 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3079 if (orient
== wxHORIZONTAL
)
3081 float fpos
= (float)pos
;
3082 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3083 if (fpos
< 0.0) fpos
= 0.0;
3084 m_oldHorizontalPos
= fpos
;
3086 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3087 m_hAdjust
->value
= fpos
;
3091 float fpos
= (float)pos
;
3092 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3093 if (fpos
< 0.0) fpos
= 0.0;
3094 m_oldVerticalPos
= fpos
;
3096 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3097 m_vAdjust
->value
= fpos
;
3104 if (m_wxwindow
->window
)
3106 if (orient
== wxHORIZONTAL
)
3107 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3109 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3116 int wxWindow::GetScrollThumb( int orient
) const
3118 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3120 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3122 if (orient
== wxHORIZONTAL
)
3123 return (int)(m_hAdjust
->page_size
+0.5);
3125 return (int)(m_vAdjust
->page_size
+0.5);
3128 int wxWindow::GetScrollPos( int orient
) const
3130 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3132 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3134 if (orient
== wxHORIZONTAL
)
3135 return (int)(m_hAdjust
->value
+0.5);
3137 return (int)(m_vAdjust
->value
+0.5);
3140 int wxWindow::GetScrollRange( int orient
) const
3142 wxCHECK_MSG( m_widget
!= NULL
, 0, wxT("invalid window") );
3144 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, wxT("window needs client area for scrolling") );
3146 if (orient
== wxHORIZONTAL
)
3147 return (int)(m_hAdjust
->upper
+0.5);
3149 return (int)(m_vAdjust
->upper
+0.5);
3152 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3154 wxCHECK_RET( m_widget
!= NULL
, wxT("invalid window") );
3156 wxCHECK_RET( m_wxwindow
!= NULL
, wxT("window needs client area for scrolling") );
3158 gtk_pizza_scroll( GTK_PIZZA(m_wxwindow
), -dx
, -dy
);
3163 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3164 gdk_gc_set_exposures( m_scrollGC, TRUE );
3167 wxNode *node = m_children.First();
3170 wxWindow *child = (wxWindow*) node->Data();
3173 child->GetSize( &sx, &sy );
3174 child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
3175 node = node->Next();
3180 GetClientSize( &cw, &ch );
3181 int w = cw - abs(dx);
3182 int h = ch - abs(dy);
3184 if ((h < 0) || (w < 0))
3192 if (dx < 0) s_x = -dx;
3193 if (dy < 0) s_y = -dy;
3196 if (dx > 0) d_x = dx;
3197 if (dy > 0) d_y = dy;
3199 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
3200 m_wxwindow->window, s_x, s_y, w, h );
3203 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3204 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3205 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3206 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
3208 Refresh( TRUE, &rect );
3213 void wxWindow::SetScrolling(bool scroll
)
3215 m_isScrolling
= g_blockEventsOnScroll
= scroll
;