]> git.saurik.com Git - wxWidgets.git/blame - src/gtk1/window.cpp
include <wx/...> => include "wx/..."
[wxWidgets.git] / src / gtk1 / window.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: window.cpp
3// Purpose:
4// Author: Robert Roebling
c67d8618 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling, Julian Smart
5e0aa05a 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
bfc6fde4 12 #pragma implementation "window.h"
c801d85f
KB
13#endif
14
15#include "wx/defs.h"
16#include "wx/window.h"
17#include "wx/dc.h"
18#include "wx/frame.h"
19#include "wx/app.h"
20#include "wx/layout.h"
21#include "wx/utils.h"
22#include "wx/dialog.h"
23#include "wx/msgdlg.h"
bfc6fde4 24
06cfab17 25#if wxUSE_DRAG_AND_DROP
bfc6fde4 26 #include "wx/dnd.h"
ac57418f 27#endif
bfc6fde4 28
cad880f5 29#if wxUSE_TOOLTIPS
bfc6fde4 30 #include "wx/tooltip.h"
cad880f5 31#endif
bfc6fde4 32
30dea054 33#include "wx/menu.h"
d4c99d6f 34#include "wx/statusbr.h"
b4071e91 35#include "wx/intl.h"
3bc755fc 36#include "wx/settings.h"
3069ac4e 37#include "wx/log.h"
b4071e91
RR
38
39#include <math.h>
c801d85f 40
83624f79
RR
41#include "gdk/gdk.h"
42#include "gtk/gtk.h"
43#include "gdk/gdkprivate.h"
44#include "gdk/gdkkeysyms.h"
45#include "wx/gtk/win_gtk.h"
46
6bc8a1c8 47#include "gdk/gdkx.h"
6bc8a1c8 48
868a2826
RR
49//-----------------------------------------------------------------------------
50// documentation on internals
51//-----------------------------------------------------------------------------
52
53/*
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
47d67540 57 some more information about what the wxWindow, which is the base class
868a2826 58 for all other window classes, does seems required as well.
47d67540 59
30760ce7
RR
60 I)
61
868a2826 62 What does wxWindow do? It contains the common interface for the following
e380f72b 63 jobs of its descendants:
47d67540 64
868a2826 65 1) Define the rudimentary behaviour common to all window classes, such as
e380f72b
RR
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.
868a2826
RR
68
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
e380f72b 71 classes which do not display a native GTK widget. To name them, these
868a2826 72 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
47d67540 73 work classes are a special case and are handled a bit differently from
e380f72b 74 the rest. The same holds true for the wxNotebook class.
47d67540 75
868a2826
RR
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
78 as above.
47d67540 79
e380f72b
RR
80 4) Provide the entire mechanism for scrolling widgets. This actual inter-
81 face for this is usually in wxScrolledWindow, but the GTK implementation
868a2826 82 is in this class.
47d67540 83
868a2826
RR
84 5) A multitude of helper or extra methods for special purposes, such as
85 Drag'n'Drop, managing validators etc.
47d67540 86
30760ce7
RR
87 6) Display a border (sunken, raised, simple or none).
88
e380f72b
RR
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
868a2826
RR
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
98 this directory.
47d67540 99
868a2826 100 All windows must have a widget, with which they interact with other under-
e380f72b 101 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
868a2826 102 thw wxWindow class has a member variable called m_widget which holds a
e380f72b
RR
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)
8bbe427f 107
e380f72b 108 When the class has a client area for drawing into and for containing children
da048e3d 109 it has to handle the client area widget (of the type GtkPizza, defined in
8bbe427f
VZ
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
da048e3d 115 the type GtkPizza.
47d67540 116
868a2826
RR
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-
da048e3d 121 Window and a m_wxwindow field that is pointer to a GtkPizza and this
868a2826 122 one is (in the GTK sense) a child of the GtkScrolledWindow.
47d67540 123
868a2826
RR
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.
30760ce7
RR
127
128 II)
129
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()
da048e3d 135 which actually moves the window and its subchildren. Note that GtkPizza
30760ce7
RR
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
da048e3d 138 in various places using the pizza->xoffset and pizza->yoffset values.
30760ce7
RR
139
140 III)
141
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
3017f78d 151 the OpenGl drawing routines rely on correct behaviour. Therefore, I have
30760ce7
RR
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
155 GTK).
156
157 IV)
158
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.
164
165 V)
166
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.
868a2826
RR
176
177*/
178
f03fc89f
VZ
179//-----------------------------------------------------------------------------
180// data
181//-----------------------------------------------------------------------------
182
183extern wxList wxPendingDelete;
184extern bool g_blockEventsOnDrag;
185extern bool g_blockEventsOnScroll;
238d735d 186extern wxCursor g_globalCursor;
72195a0f 187static wxWindow *g_captureWindow = (wxWindow*) NULL;
65045edd 188 wxWindow *g_focusWindow = (wxWindow*) NULL;
f03fc89f
VZ
189
190/* hack: we need something to pass to gtk_menu_popup, so we store the time of
191 the last click here */
192static guint32 gs_timeLastClick = 0;
193
2e563988
RR
194//-----------------------------------------------------------------------------
195// debug
196//-----------------------------------------------------------------------------
197
198#ifdef __WXDEBUG__
199
200static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget),
201 GdkEvent *WXUNUSED(event),
014b0d06 202 const wxChar *WXUNUSED(name) )
2e563988 203{
053dcf1a 204/*
167e3718
VZ
205 static bool s_done = FALSE;
206 if ( !s_done )
207 {
208 wxLog::AddTraceMask("focus");
209 s_done = TRUE;
210 }
223d09f6 211 wxLogTrace(wxT("FOCUS NOW AT: %s"), name);
053dcf1a 212*/
2e563988
RR
213
214 return FALSE;
215}
216
217void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window )
218{
219 wxString tmp = name;
223d09f6 220 tmp += wxT(" FROM ");
2e563988
RR
221 tmp += window;
222
223 wxChar *s = new wxChar[tmp.Length()+1];
224
225 wxStrcpy( s, tmp );
226
227 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
228 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s );
229}
230
f03fc89f 231#endif // Debug
ff8bfdbb 232
85eb36c2
RR
233//-----------------------------------------------------------------------------
234// missing gdk functions
235//-----------------------------------------------------------------------------
236
237void
238gdk_window_warp_pointer (GdkWindow *window,
c50f1fb9
VZ
239 gint x,
240 gint y)
85eb36c2
RR
241{
242 GdkWindowPrivate *priv;
c50f1fb9 243
85eb36c2
RR
244 if (!window)
245 window = (GdkWindow*) &gdk_root_parent;
c50f1fb9 246
85eb36c2 247 priv = (GdkWindowPrivate*) window;
c50f1fb9 248
85eb36c2
RR
249 if (!priv->destroyed)
250 {
c50f1fb9 251 XWarpPointer (priv->xdisplay,
85eb36c2 252 None, /* not source window -> move from anywhere */
c50f1fb9 253 priv->xwindow, /* dest window */
85eb36c2 254 0, 0, 0, 0, /* not source window -> move from anywhere */
c50f1fb9 255 x, y );
85eb36c2
RR
256 }
257}
258
acfd422a 259//-----------------------------------------------------------------------------
a2053b27 260// idle system
acfd422a
RR
261//-----------------------------------------------------------------------------
262
a2053b27
RR
263extern void wxapp_install_idle_handler();
264extern bool g_isIdle;
265
ed673c6a
RR
266//-----------------------------------------------------------------------------
267// local code (see below)
268//-----------------------------------------------------------------------------
269
ed673c6a
RR
270static void draw_frame( GtkWidget *widget, wxWindow *win )
271{
272 if (!win->m_hasVMT)
273 return;
274
275 int dw = 0;
276 int dh = 0;
277
278 if (win->HasScrolling())
279 {
280 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget);
281 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass );
282
283/*
284 GtkWidget *hscrollbar = scroll_window->hscrollbar;
285 GtkWidget *vscrollbar = scroll_window->vscrollbar;
286
287 we use this instead: range.slider_width = 11 + 2*2pts edge
288*/
289
290 if (scroll_window->vscrollbar_visible)
291 {
292 dw += 15; /* dw += vscrollbar->allocation.width; */
293 dw += scroll_class->scrollbar_spacing;
294 }
295
296 if (scroll_window->hscrollbar_visible)
297 {
298 dh += 15; /* dh += hscrollbar->allocation.height; */
299 dh += scroll_class->scrollbar_spacing;
300 }
301 }
302
303 int dx = 0;
304 int dy = 0;
305 if (GTK_WIDGET_NO_WINDOW (widget))
306 {
307 dx += widget->allocation.x;
308 dy += widget->allocation.y;
309 }
310
311 if (win->HasFlag(wxRAISED_BORDER))
312 {
313 gtk_draw_shadow( widget->style,
314 widget->window,
315 GTK_STATE_NORMAL,
316 GTK_SHADOW_OUT,
317 dx, dy,
318 win->m_width-dw, win->m_height-dh );
319 return;
320 }
321
322 if (win->HasFlag(wxSUNKEN_BORDER))
323 {
324 gtk_draw_shadow( widget->style,
325 widget->window,
326 GTK_STATE_NORMAL,
327 GTK_SHADOW_IN,
328 dx, dy,
329 win->m_width-dw, win->m_height-dh );
330 return;
331 }
332
333 if (win->HasFlag(wxSIMPLE_BORDER))
334 {
335 GdkGC *gc;
336 gc = gdk_gc_new( widget->window );
337 gdk_gc_set_foreground( gc, &widget->style->black );
338 gdk_draw_rectangle( widget->window, gc, FALSE,
339 dx, dy,
340 win->m_width-dw-1, win->m_height-dh-1 );
341 gdk_gc_unref( gc );
342 return;
343 }
344}
345
346//-----------------------------------------------------------------------------
347// "expose_event" of m_widget
348//-----------------------------------------------------------------------------
349
350static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
351{
352 if (gdk_event->count > 0) return;
353 draw_frame( widget, win );
354}
355
356//-----------------------------------------------------------------------------
147bc491 357// "draw" of m_widget
ed673c6a
RR
358//-----------------------------------------------------------------------------
359
360static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindow *win )
361{
362 draw_frame( widget, win );
363}
364
c5b42c87 365//-----------------------------------------------------------------------------
da048e3d 366// key code mapping routines
c5b42c87
RR
367//-----------------------------------------------------------------------------
368
369static long map_to_unmodified_wx_keysym( KeySym keysym )
370{
371 guint key_code = 0;
372
373 switch (keysym)
374 {
375 case GDK_Shift_L:
376 case GDK_Shift_R: key_code = WXK_SHIFT; break;
377 case GDK_Control_L:
378 case GDK_Control_R: key_code = WXK_CONTROL; break;
c50f1fb9
VZ
379 case GDK_Meta_L:
380 case GDK_Meta_R:
381 case GDK_Alt_L:
382 case GDK_Alt_R:
383 case GDK_Super_L:
384 case GDK_Super_R: key_code = WXK_ALT; break;
c5b42c87
RR
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;
413
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;
21884766 438 case GDK_KP_Next: key_code = WXK_NUMPAD_NEXT; break;
c5b42c87
RR
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;
c50f1fb9 451
c5b42c87
RR
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;
464 default:
465 {
466 if (keysym <= 0xFF)
467 {
468 guint upper = gdk_keyval_to_upper( keysym );
469 keysym = (upper != 0 ? upper : keysym ); /* to be MSW compatible */
470 key_code = keysym;
471 }
472 }
473 }
474
475 return (key_code);
476}
477
478static long map_to_wx_keysym( KeySym keysym )
479{
480 guint key_code = 0;
481
482 switch (keysym)
483 {
c5b42c87
RR
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;
512
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;
21884766 537 case GDK_KP_Next: key_code = WXK_NEXT; break;
c5b42c87
RR
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;
c50f1fb9 550
c5b42c87
RR
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;
563 default:
564 {
565 if (keysym <= 0xFF)
566 {
567 key_code = keysym;
568 }
569 }
570 }
571
572 return (key_code);
573}
574
c801d85f 575//-----------------------------------------------------------------------------
034be888 576// "expose_event" of m_wxwindow
c801d85f
KB
577//-----------------------------------------------------------------------------
578
2f2aa628 579static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win )
47d67540 580{
98d3fdbe
RR
581 if (!win->m_hasVMT)
582 return;
583
f03fc89f
VZ
584 win->GetUpdateRegion().Union( gdk_event->area.x,
585 gdk_event->area.y,
586 gdk_event->area.width,
587 gdk_event->area.height );
47d67540 588
98d3fdbe 589 if (gdk_event->count > 0)
f03fc89f 590 return;
c801d85f 591
98d3fdbe
RR
592/*
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 );
600*/
6a008b33 601
54517652
RR
602 wxEraseEvent eevent( win->GetId() );
603 eevent.SetEventObject( win );
604 win->GetEventHandler()->ProcessEvent(eevent);
605
f7a11f8c
RR
606 wxPaintEvent event( win->GetId() );
607 event.SetEventObject( win );
608 win->GetEventHandler()->ProcessEvent( event );
609
f03fc89f 610 win->GetUpdateRegion().Clear();
362c6693 611}
c801d85f
KB
612
613//-----------------------------------------------------------------------------
034be888 614// "draw" of m_wxwindow
2f2aa628 615//-----------------------------------------------------------------------------
c801d85f 616
f7a11f8c 617static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
47d67540 618{
c50f1fb9 619 if (g_isIdle)
a2053b27
RR
620 wxapp_install_idle_handler();
621
622 if (!win->m_hasVMT)
f03fc89f 623 return;
47d67540 624
f03fc89f
VZ
625 win->GetUpdateRegion().Union( rect->x, rect->y,
626 rect->width, rect->height );
47d67540 627
98d3fdbe
RR
628/*
629 wxPrintf( "OnDraw from " );
630 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
631 printf( win->GetClassInfo()->GetClassName() );
632 wxPrintf( " %d %d %d %d\n", (int)rect->x,
633 (int)rect->y,
634 (int)rect->width,
635 (int)rect->height );
636*/
f7a11f8c 637
54517652
RR
638 wxEraseEvent eevent( win->GetId() );
639 eevent.SetEventObject( win );
640 win->GetEventHandler()->ProcessEvent(eevent);
641
f7a11f8c
RR
642 wxPaintEvent event( win->GetId() );
643 event.SetEventObject( win );
f5e27805 644 win->GetEventHandler()->ProcessEvent( event );
47d67540 645
f03fc89f 646 win->GetUpdateRegion().Clear();
362c6693 647}
c801d85f
KB
648
649//-----------------------------------------------------------------------------
b292e2f5 650// "key_press_event" from any window
c801d85f 651//-----------------------------------------------------------------------------
c801d85f 652
2f2aa628 653static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
47d67540 654{
c50f1fb9 655 if (g_isIdle)
a2053b27
RR
656 wxapp_install_idle_handler();
657
658 if (!win->m_hasVMT) return FALSE;
f5e27805 659 if (g_blockEventsOnDrag) return FALSE;
c801d85f 660
7be4c594 661/*
d1367c3d
RR
662 printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
663 if (gdk_event->state & GDK_SHIFT_MASK)
664 printf( "ShiftDown.\n" );
665 else
666 printf( "ShiftUp.\n" );
667 if (gdk_event->state & GDK_CONTROL_MASK)
668 printf( "ControlDown.\n" );
669 else
670 printf( "ControlUp.\n" );
671 printf( "\n" );
7be4c594 672*/
b0e813a0
RR
673 int x = 0;
674 int y = 0;
675 GdkModifierType state;
676 if (gdk_event->window) gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
47d67540 677
3017f78d
RR
678 bool ret = FALSE;
679
74505862 680 long key_code = map_to_unmodified_wx_keysym( gdk_event->keyval );
f0492f7d
RR
681 /* sending unknown key events doesn't really make sense */
682 if (key_code == 0) return FALSE;
683
c50f1fb9 684 wxKeyEvent event( wxEVT_KEY_DOWN );
d1367c3d 685 event.SetTimestamp( gdk_event->time );
f5e27805
RR
686 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
687 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
688 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
689 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
690 event.m_keyCode = key_code;
b0e813a0
RR
691 event.m_scanCode = gdk_event->keyval;
692 event.m_x = x;
693 event.m_y = y;
f5e27805 694 event.SetEventObject( win );
c5b42c87 695 ret = win->GetEventHandler()->ProcessEvent( event );
c50f1fb9 696
88ac883a 697#if wxUSE_ACCEL
f5e27805 698 if (!ret)
47d67540 699 {
f5e27805
RR
700 wxWindow *ancestor = win;
701 while (ancestor)
702 {
703 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
704 if (command != -1)
705 {
706 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
707 ret = ancestor->GetEventHandler()->ProcessEvent( command_event );
708 break;
709 }
da048e3d
RR
710 if (ancestor->m_isFrame)
711 break;
f5e27805
RR
712 ancestor = ancestor->GetParent();
713 }
bcf1fa6b 714 }
88ac883a 715#endif // wxUSE_ACCEL
3017f78d 716
d728dd40
KB
717 /* wxMSW doesn't send char events with Alt pressed */
718 /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
3017f78d
RR
719 will only be sent if it is not in an accelerator table. */
720 key_code = map_to_wx_keysym( gdk_event->keyval );
721
722 if ( (!ret) &&
723 (key_code != 0))
d728dd40 724 {
c50f1fb9 725 wxKeyEvent event2( wxEVT_CHAR );
d728dd40
KB
726 event2.SetTimestamp( gdk_event->time );
727 event2.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
728 event2.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
729 event2.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
730 event2.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
731 event2.m_keyCode = key_code;
732 event2.m_scanCode = gdk_event->keyval;
733 event2.m_x = x;
734 event2.m_y = y;
735 event2.SetEventObject( win );
3017f78d 736 ret = win->GetEventHandler()->ProcessEvent( event2 );
d728dd40
KB
737 }
738
053f9cc1 739 /* win is a control: tab can be propagated up */
ca298c88 740 if ( (!ret) &&
5664fc32 741 ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
3da17724
RR
742 (!win->HasFlag(wxTE_PROCESS_TAB)) &&
743 (win->GetParent()) &&
744 (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
b292e2f5
RR
745 {
746 wxNavigationKeyEvent new_event;
3da17724 747 new_event.SetEventObject( win );
f03fc89f 748 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
5664fc32 749 new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
f03fc89f 750 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
b98d804b 751 new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
b292e2f5 752 new_event.SetCurrentFocus( win );
ff8bfdbb 753 ret = win->GetEventHandler()->ProcessEvent( new_event );
b292e2f5 754 }
ff8bfdbb 755
801aa178 756 /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
ca298c88 757 if ( (!ret) &&
b98d804b
RR
758 (gdk_event->keyval == GDK_Escape) )
759 {
760 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
761 new_event.SetEventObject( win );
762 ret = win->GetEventHandler()->ProcessEvent( new_event );
763 }
c50f1fb9 764
6bc8a1c8 765#if (GTK_MINOR_VERSION > 0)
da048e3d
RR
766 /* Pressing F10 will activate the menu bar of the top frame. */
767 /* Doesn't work. */
3017f78d 768/*
801aa178
RR
769 if ( (!ret) &&
770 (gdk_event->keyval == GDK_F10) )
771 {
772 wxWindow *ancestor = win;
773 while (ancestor)
774 {
775 if (wxIsKindOf(ancestor,wxFrame))
c50f1fb9
VZ
776 {
777 wxFrame *frame = (wxFrame*) ancestor;
801aa178 778 wxMenuBar *menubar = frame->GetMenuBar();
c50f1fb9
VZ
779 if (menubar)
780 {
801aa178 781 wxNode *node = menubar->GetMenus().First();
c50f1fb9
VZ
782 if (node)
783 {
3017f78d
RR
784 wxMenu *firstMenu = (wxMenu*) node->Data();
785 gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
786 ret = TRUE;
c50f1fb9
VZ
787 break;
788 }
789 }
790 }
801aa178
RR
791 ancestor = ancestor->GetParent();
792 }
793 }
3017f78d 794*/
6bc8a1c8 795#endif
ca298c88 796
b292e2f5 797/*
b98d804b
RR
798 Damn, I forgot why this didn't work, but it didn't work.
799
b292e2f5 800 // win is a panel: up can be propagated to the panel
a2053b27 801 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
b292e2f5
RR
802 (gdk_event->keyval == GDK_Up))
803 {
804 win->m_parent->SetFocus();
ff8bfdbb 805 ret = TRUE;
b292e2f5 806 }
ff8bfdbb 807
b292e2f5 808 // win is a panel: left/right can be propagated to the panel
a2053b27 809 if ((!ret) && (win->m_wxwindow) &&
ff8bfdbb 810 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
b292e2f5
RR
811 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
812 {
813 wxNavigationKeyEvent new_event;
814 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
815 new_event.SetCurrentFocus( win );
ff8bfdbb 816 ret = win->GetEventHandler()->ProcessEvent( new_event );
b292e2f5
RR
817 }
818*/
ff8bfdbb 819
f5e27805
RR
820 if (ret)
821 {
b292e2f5 822 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
f03fc89f 823 return TRUE;
f5e27805 824 }
47d67540 825
034be888 826 return FALSE;
362c6693 827}
c801d85f 828
b666df2c
RR
829//-----------------------------------------------------------------------------
830// "key_release_event" from any window
831//-----------------------------------------------------------------------------
832
833static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
834{
c50f1fb9 835 if (g_isIdle)
a2053b27
RR
836 wxapp_install_idle_handler();
837
838 if (!win->m_hasVMT) return FALSE;
b666df2c
RR
839 if (g_blockEventsOnDrag) return FALSE;
840
841/*
d1367c3d
RR
842 printf( "KeyUp-ScanCode is: %d.\n", gdk_event->keyval );
843 if (gdk_event->state & GDK_SHIFT_MASK)
844 printf( "ShiftDown.\n" );
845 else
846 printf( "ShiftUp.\n" );
847 if (gdk_event->state & GDK_CONTROL_MASK)
848 printf( "ControlDown.\n" );
849 else
850 printf( "ControlUp.\n" );
851 printf( "\n" );
b666df2c
RR
852*/
853
74505862 854 long key_code = map_to_unmodified_wx_keysym( gdk_event->keyval );
c50f1fb9 855
f0492f7d
RR
856 /* sending unknown key events doesn't really make sense */
857 if (key_code == 0) return FALSE;
b666df2c 858
b0e813a0
RR
859 int x = 0;
860 int y = 0;
861 GdkModifierType state;
862 if (gdk_event->window) gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
b666df2c
RR
863
864 wxKeyEvent event( wxEVT_KEY_UP );
d1367c3d 865 event.SetTimestamp( gdk_event->time );
b666df2c
RR
866 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
867 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
868 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
869 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
870 event.m_keyCode = key_code;
b0e813a0
RR
871 event.m_scanCode = gdk_event->keyval;
872 event.m_x = x;
873 event.m_y = y;
b666df2c
RR
874 event.SetEventObject( win );
875
034be888 876 if (win->GetEventHandler()->ProcessEvent( event ))
b666df2c 877 {
b98d804b 878 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_release_event" );
f03fc89f 879 return TRUE;
b666df2c
RR
880 }
881
034be888 882 return FALSE;
b666df2c
RR
883}
884
c801d85f 885//-----------------------------------------------------------------------------
2f2aa628
RR
886// "button_press_event"
887//-----------------------------------------------------------------------------
c801d85f 888
2f2aa628 889static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
903f689b 890{
c50f1fb9 891 if (g_isIdle)
a2053b27
RR
892 wxapp_install_idle_handler();
893
894/*
223d09f6 895 wxPrintf( wxT("1) OnButtonPress from ") );
a2053b27
RR
896 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
897 wxPrintf( win->GetClassInfo()->GetClassName() );
223d09f6 898 wxPrintf( wxT(".\n") );
a2053b27 899*/
a2053b27 900 if (!win->m_hasVMT) return FALSE;
f5e27805 901 if (g_blockEventsOnDrag) return TRUE;
76ed8f8d 902 if (g_blockEventsOnScroll) return TRUE;
c801d85f 903
034be888
RR
904 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
905
a2053b27 906 if (win->m_wxwindow)
c801d85f 907 {
a2053b27 908 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow) && !GTK_WIDGET_HAS_FOCUS (win->m_wxwindow) )
f5e27805 909 {
a2053b27 910 gtk_widget_grab_focus (win->m_wxwindow);
47d67540 911
c801d85f 912/*
223d09f6 913 wxPrintf( wxT("GrabFocus from ") );
f5e27805 914 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
a2053b27 915 wxPrintf( win->GetClassInfo()->GetClassName() );
223d09f6 916 wxPrintf( wxT(".\n") );
c801d85f 917*/
47d67540 918
f5e27805 919 }
362c6693 920 }
47d67540 921
f5e27805 922 wxEventType event_type = wxEVT_LEFT_DOWN;
47d67540 923
f5e27805 924 if (gdk_event->button == 1)
c801d85f 925 {
f5e27805
RR
926 switch (gdk_event->type)
927 {
928 case GDK_BUTTON_PRESS: event_type = wxEVT_LEFT_DOWN; break;
929 case GDK_2BUTTON_PRESS: event_type = wxEVT_LEFT_DCLICK; break;
930 default: break;
931 }
362c6693 932 }
f5e27805 933 else if (gdk_event->button == 2)
c801d85f 934 {
f5e27805
RR
935 switch (gdk_event->type)
936 {
937 case GDK_BUTTON_PRESS: event_type = wxEVT_MIDDLE_DOWN; break;
938 case GDK_2BUTTON_PRESS: event_type = wxEVT_MIDDLE_DCLICK; break;
939 default: break;
940 }
362c6693 941 }
f5e27805 942 else if (gdk_event->button == 3)
c801d85f 943 {
f5e27805
RR
944 switch (gdk_event->type)
945 {
946 case GDK_BUTTON_PRESS: event_type = wxEVT_RIGHT_DOWN; break;
947 case GDK_2BUTTON_PRESS: event_type = wxEVT_RIGHT_DCLICK; break;
948 default: break;
949 }
362c6693 950 }
47d67540 951
f5e27805 952 wxMouseEvent event( event_type );
d1367c3d 953 event.SetTimestamp( gdk_event->time );
f5e27805
RR
954 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
955 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
956 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
957 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
958 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
959 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
960 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
47d67540 961
f5e27805
RR
962 event.m_x = (long)gdk_event->x;
963 event.m_y = (long)gdk_event->y;
47d67540 964
f5e27805
RR
965 // Some control don't have their own X window and thus cannot get
966 // any events.
47d67540 967
72195a0f 968 if (!g_captureWindow)
2f2aa628 969 {
2f073eb2
RR
970 int x = event.m_x;
971 int y = event.m_y;
972 if (win->m_wxwindow)
973 {
da048e3d
RR
974 GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow);
975 x += pizza->xoffset;
976 y += pizza->yoffset;
2f073eb2
RR
977 }
978
db1b4961 979 wxNode *node = win->GetChildren().First();
f5e27805
RR
980 while (node)
981 {
982 wxWindow *child = (wxWindow*)node->Data();
f96ac56a
RR
983
984 node = node->Next();
985 if (!child->IsShown())
986 continue;
ff8bfdbb 987
a2053b27 988 if (child->m_isStaticBox)
ff8bfdbb
VZ
989 {
990 // wxStaticBox is transparent in the box itself
a2053b27
RR
991 int xx1 = child->m_x;
992 int yy1 = child->m_y;
993 int xx2 = child->m_x + child->m_width;
994 int yy2 = child->m_x + child->m_height;
ff8bfdbb
VZ
995
996 // left
997 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
998 // right
999 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
1000 // top
1001 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
1002 // bottom
1003 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
1004 {
1ecc4d80 1005 win = child;
a2053b27
RR
1006 event.m_x -= child->m_x;
1007 event.m_y -= child->m_y;
1ecc4d80 1008 break;
ff8bfdbb
VZ
1009 }
1010
1011 }
1012 else
1013 {
a2053b27 1014 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
2f073eb2
RR
1015 (child->m_x <= x) &&
1016 (child->m_y <= y) &&
1017 (child->m_x+child->m_width >= x) &&
1018 (child->m_y+child->m_height >= y))
1ecc4d80
RR
1019 {
1020 win = child;
a2053b27
RR
1021 event.m_x -= child->m_x;
1022 event.m_y -= child->m_y;
1ecc4d80 1023 break;
ff8bfdbb 1024 }
f5e27805 1025 }
f5e27805 1026 }
2f2aa628 1027 }
ff8bfdbb 1028
f5e27805 1029 event.SetEventObject( win );
47d67540 1030
f5e27805 1031 gs_timeLastClick = gdk_event->time;
47d67540 1032
2f073eb2
RR
1033/*
1034 wxPrintf( wxT("2) OnButtonPress from ") );
1035 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1036 wxPrintf( win->GetClassInfo()->GetClassName() );
1037 wxPrintf( wxT(".\n") );
1038*/
1039
f5e27805 1040 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1041 {
f5e27805 1042 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_press_event" );
f03fc89f 1043 return TRUE;
034be888 1044 }
47d67540 1045
034be888 1046 return FALSE;
362c6693 1047}
c801d85f
KB
1048
1049//-----------------------------------------------------------------------------
97b3455a 1050// "button_release_event"
2f2aa628 1051//-----------------------------------------------------------------------------
c801d85f 1052
2f2aa628 1053static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
47d67540 1054{
c50f1fb9 1055 if (g_isIdle)
a2053b27
RR
1056 wxapp_install_idle_handler();
1057
1058 if (!win->m_hasVMT) return FALSE;
034be888
RR
1059 if (g_blockEventsOnDrag) return FALSE;
1060 if (g_blockEventsOnScroll) return FALSE;
c801d85f 1061
034be888 1062 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
47d67540 1063
c801d85f 1064/*
f5e27805
RR
1065 printf( "OnButtonRelease from " );
1066 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1067 printf( win->GetClassInfo()->GetClassName() );
1068 printf( ".\n" );
c801d85f 1069*/
47d67540 1070
f5e27805 1071 wxEventType event_type = wxEVT_NULL;
47d67540 1072
f5e27805
RR
1073 switch (gdk_event->button)
1074 {
1075 case 1: event_type = wxEVT_LEFT_UP; break;
1076 case 2: event_type = wxEVT_MIDDLE_UP; break;
1077 case 3: event_type = wxEVT_RIGHT_UP; break;
1078 }
47d67540 1079
f5e27805 1080 wxMouseEvent event( event_type );
d1367c3d 1081 event.SetTimestamp( gdk_event->time );
f5e27805
RR
1082 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
1083 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
1084 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
1085 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
1086 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
1087 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
1088 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
1089 event.m_x = (long)gdk_event->x;
1090 event.m_y = (long)gdk_event->y;
1091
1092 // Some control don't have their own X window and thus cannot get
1093 // any events.
1094
72195a0f 1095 if (!g_captureWindow)
2f2aa628 1096 {
2f073eb2
RR
1097 int x = event.m_x;
1098 int y = event.m_y;
1099 if (win->m_wxwindow)
1100 {
da048e3d
RR
1101 GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow);
1102 x += pizza->xoffset;
1103 y += pizza->yoffset;
2f073eb2
RR
1104 }
1105
db1b4961 1106 wxNode *node = win->GetChildren().First();
f5e27805
RR
1107 while (node)
1108 {
1109 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb 1110
f96ac56a
RR
1111 node = node->Next();
1112 if (!child->IsShown())
1113 continue;
1114
a2053b27 1115 if (child->m_isStaticBox)
ff8bfdbb
VZ
1116 {
1117 // wxStaticBox is transparent in the box itself
a2053b27
RR
1118 int xx1 = child->m_x;
1119 int yy1 = child->m_y;
1120 int xx2 = child->m_x + child->m_width;
1121 int yy2 = child->m_x + child->m_height;
ff8bfdbb
VZ
1122
1123 // left
1124 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
1125 // right
1126 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
1127 // top
1128 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
1129 // bottom
1130 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
1131 {
1ecc4d80 1132 win = child;
a2053b27
RR
1133 event.m_x -= child->m_x;
1134 event.m_y -= child->m_y;
1ecc4d80 1135 break;
ff8bfdbb
VZ
1136 }
1137
1138 }
1139 else
1140 {
a2053b27 1141 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
2f073eb2
RR
1142 (child->m_x <= x) &&
1143 (child->m_y <= y) &&
1144 (child->m_x+child->m_width >= x) &&
1145 (child->m_y+child->m_height >= y))
1ecc4d80
RR
1146 {
1147 win = child;
a2053b27
RR
1148 event.m_x -= child->m_x;
1149 event.m_y -= child->m_y;
1ecc4d80 1150 break;
ff8bfdbb 1151 }
f5e27805 1152 }
f5e27805 1153 }
2f2aa628 1154 }
47d67540 1155
f5e27805 1156 event.SetEventObject( win );
47d67540 1157
f5e27805 1158 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1159 {
f5e27805 1160 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_release_event" );
f03fc89f 1161 return TRUE;
034be888 1162 }
47d67540 1163
034be888 1164 return FALSE;
362c6693 1165}
c801d85f
KB
1166
1167//-----------------------------------------------------------------------------
2f2aa628
RR
1168// "motion_notify_event"
1169//-----------------------------------------------------------------------------
c801d85f 1170
2f2aa628 1171static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
47d67540 1172{
c50f1fb9 1173 if (g_isIdle)
a2053b27
RR
1174 wxapp_install_idle_handler();
1175
1176 if (!win->m_hasVMT) return FALSE;
034be888
RR
1177 if (g_blockEventsOnDrag) return FALSE;
1178 if (g_blockEventsOnScroll) return FALSE;
5e014a0c 1179
034be888
RR
1180 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
1181
ff8bfdbb 1182 if (gdk_event->is_hint)
aae24d21 1183 {
f7a11f8c
RR
1184 int x = 0;
1185 int y = 0;
1186 GdkModifierType state;
1187 gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
1188 gdk_event->x = x;
1189 gdk_event->y = y;
aae24d21 1190 }
ff8bfdbb 1191
c801d85f 1192/*
e380f72b
RR
1193 printf( "OnMotion from " );
1194 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1195 printf( win->GetClassInfo()->GetClassName() );
1196 printf( ".\n" );
aae24d21 1197*/
47d67540 1198
e380f72b 1199 wxMouseEvent event( wxEVT_MOTION );
d1367c3d 1200 event.SetTimestamp( gdk_event->time );
e380f72b
RR
1201 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
1202 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
1203 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
1204 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
1205 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
1206 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
1207 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
1208
1209 event.m_x = (long)gdk_event->x;
1210 event.m_y = (long)gdk_event->y;
1211
1212 // Some control don't have their own X window and thus cannot get
1213 // any events.
1214
72195a0f 1215 if (!g_captureWindow)
2f2aa628 1216 {
2f073eb2
RR
1217 int x = event.m_x;
1218 int y = event.m_y;
1219 if (win->m_wxwindow)
1220 {
da048e3d
RR
1221 GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow);
1222 x += pizza->xoffset;
1223 y += pizza->yoffset;
2f073eb2
RR
1224 }
1225
db1b4961 1226 wxNode *node = win->GetChildren().First();
e380f72b
RR
1227 while (node)
1228 {
1229 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb 1230
f96ac56a
RR
1231 node = node->Next();
1232 if (!child->IsShown())
1233 continue;
1234
a2053b27 1235 if (child->m_isStaticBox)
ff8bfdbb
VZ
1236 {
1237 // wxStaticBox is transparent in the box itself
a2053b27
RR
1238 int xx1 = child->m_x;
1239 int yy1 = child->m_y;
1240 int xx2 = child->m_x + child->m_width;
1241 int yy2 = child->m_x + child->m_height;
ff8bfdbb
VZ
1242
1243 // left
1244 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
1245 // right
1246 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
1247 // top
1248 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
1249 // bottom
1250 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
1251 {
1ecc4d80 1252 win = child;
a2053b27
RR
1253 event.m_x -= child->m_x;
1254 event.m_y -= child->m_y;
1ecc4d80 1255 break;
ff8bfdbb
VZ
1256 }
1257
1258 }
1259 else
1260 {
a2053b27 1261 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
2f073eb2
RR
1262 (child->m_x <= x) &&
1263 (child->m_y <= y) &&
1264 (child->m_x+child->m_width >= x) &&
1265 (child->m_y+child->m_height >= y))
1ecc4d80
RR
1266 {
1267 win = child;
a2053b27
RR
1268 event.m_x -= child->m_x;
1269 event.m_y -= child->m_y;
1ecc4d80 1270 break;
ff8bfdbb 1271 }
e380f72b 1272 }
e380f72b 1273 }
2f2aa628 1274 }
47d67540 1275
e380f72b 1276 event.SetEventObject( win );
47d67540 1277
e380f72b 1278 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1279 {
e380f72b 1280 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "motion_notify_event" );
f03fc89f 1281 return TRUE;
034be888 1282 }
47d67540 1283
034be888 1284 return FALSE;
362c6693 1285}
c801d85f
KB
1286
1287//-----------------------------------------------------------------------------
2f2aa628
RR
1288// "focus_in_event"
1289//-----------------------------------------------------------------------------
c801d85f 1290
2f2aa628 1291static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 1292{
c50f1fb9 1293 if (g_isIdle)
a2053b27
RR
1294 wxapp_install_idle_handler();
1295
1296 if (!win->m_hasVMT) return FALSE;
034be888 1297 if (g_blockEventsOnDrag) return FALSE;
ff8bfdbb 1298
b292e2f5 1299 g_focusWindow = win;
ff8bfdbb 1300
c801d85f 1301/*
f03fc89f 1302 printf( "OnSetFocus from " );
e380f72b 1303 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
f03fc89f
VZ
1304 printf( win->GetClassInfo()->GetClassName() );
1305 printf( " " );
1306 printf( WXSTRINGCAST win->GetLabel() );
1307 printf( ".\n" );
c801d85f 1308*/
47d67540 1309
3da17724
RR
1310 wxPanel *panel = wxDynamicCast(win->GetParent(), wxPanel);
1311 if (panel)
1312 {
1313 panel->SetLastFocus(win);
1314 }
1315
e380f72b
RR
1316 wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
1317 event.SetEventObject( win );
47d67540 1318
e380f72b 1319 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1320 {
e380f72b 1321 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
034be888
RR
1322 return TRUE;
1323 }
ca298c88 1324
034be888 1325 return FALSE;
362c6693 1326}
c801d85f
KB
1327
1328//-----------------------------------------------------------------------------
2f2aa628
RR
1329// "focus_out_event"
1330//-----------------------------------------------------------------------------
c801d85f 1331
2f2aa628 1332static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 1333{
c50f1fb9 1334 if (g_isIdle)
a2053b27
RR
1335 wxapp_install_idle_handler();
1336
1337 if (!win->m_hasVMT) return FALSE;
034be888 1338 if (g_blockEventsOnDrag) return FALSE;
ca298c88 1339
c801d85f 1340/*
f03fc89f 1341 printf( "OnKillFocus from " );
e380f72b 1342 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
f03fc89f
VZ
1343 printf( win->GetClassInfo()->GetClassName() );
1344 printf( ".\n" );
c801d85f 1345*/
47d67540 1346
e380f72b
RR
1347 wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
1348 event.SetEventObject( win );
47d67540 1349
e380f72b 1350 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1351 {
e380f72b 1352 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" );
034be888
RR
1353 return TRUE;
1354 }
ca298c88 1355
034be888 1356 return FALSE;
362c6693 1357}
c801d85f 1358
b4071e91
RR
1359//-----------------------------------------------------------------------------
1360// "enter_notify_event"
1361//-----------------------------------------------------------------------------
1362
1363static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
1364{
c50f1fb9 1365 if (g_isIdle)
a2053b27 1366 wxapp_install_idle_handler();
ca298c88 1367
a2053b27
RR
1368 if (!win->m_hasVMT) return FALSE;
1369 if (g_blockEventsOnDrag) return FALSE;
47d67540 1370
a2053b27 1371 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
b292e2f5 1372
e380f72b 1373 wxMouseEvent event( wxEVT_ENTER_WINDOW );
6bc8a1c8 1374#if (GTK_MINOR_VERSION > 0)
d1367c3d 1375 event.SetTimestamp( gdk_event->time );
6bc8a1c8 1376#endif
e380f72b 1377 event.SetEventObject( win );
ff8bfdbb 1378
4a33eba6
RR
1379 int x = 0;
1380 int y = 0;
1381 GdkModifierType state = (GdkModifierType)0;
ff8bfdbb 1382
a2053b27 1383 gdk_window_get_pointer( widget->window, &x, &y, &state );
ff8bfdbb 1384
4a33eba6
RR
1385 event.m_shiftDown = (state & GDK_SHIFT_MASK);
1386 event.m_controlDown = (state & GDK_CONTROL_MASK);
1387 event.m_altDown = (state & GDK_MOD1_MASK);
1388 event.m_metaDown = (state & GDK_MOD2_MASK);
1389 event.m_leftDown = (state & GDK_BUTTON1_MASK);
1390 event.m_middleDown = (state & GDK_BUTTON2_MASK);
1391 event.m_rightDown = (state & GDK_BUTTON3_MASK);
1392
1393 event.m_x = (long)x;
1394 event.m_y = (long)y;
ff8bfdbb 1395
e380f72b 1396 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1397 {
e380f72b 1398 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "enter_notify_event" );
034be888
RR
1399 return TRUE;
1400 }
ca298c88 1401
034be888 1402 return FALSE;
b4071e91 1403}
47d67540 1404
b4071e91
RR
1405//-----------------------------------------------------------------------------
1406// "leave_notify_event"
1407//-----------------------------------------------------------------------------
1408
1409static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
1410{
c50f1fb9 1411 if (g_isIdle)
a2053b27 1412 wxapp_install_idle_handler();
acfd422a 1413
a2053b27
RR
1414 if (!win->m_hasVMT) return FALSE;
1415 if (g_blockEventsOnDrag) return FALSE;
b292e2f5 1416
a2053b27 1417 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
c50f1fb9 1418
e380f72b 1419 wxMouseEvent event( wxEVT_LEAVE_WINDOW );
6bc8a1c8 1420#if (GTK_MINOR_VERSION > 0)
d1367c3d 1421 event.SetTimestamp( gdk_event->time );
6bc8a1c8 1422#endif
e380f72b 1423 event.SetEventObject( win );
47d67540 1424
4a33eba6
RR
1425 int x = 0;
1426 int y = 0;
1427 GdkModifierType state = (GdkModifierType)0;
ff8bfdbb 1428
4a33eba6 1429 gdk_window_get_pointer( widget->window, &x, &y, &state );
ff8bfdbb 1430
4a33eba6
RR
1431 event.m_shiftDown = (state & GDK_SHIFT_MASK);
1432 event.m_controlDown = (state & GDK_CONTROL_MASK);
1433 event.m_altDown = (state & GDK_MOD1_MASK);
1434 event.m_metaDown = (state & GDK_MOD2_MASK);
1435 event.m_leftDown = (state & GDK_BUTTON1_MASK);
1436 event.m_middleDown = (state & GDK_BUTTON2_MASK);
1437 event.m_rightDown = (state & GDK_BUTTON3_MASK);
1438
1439 event.m_x = (long)x;
1440 event.m_y = (long)y;
ff8bfdbb 1441
e380f72b 1442 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1443 {
e380f72b 1444 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "leave_notify_event" );
034be888
RR
1445 return TRUE;
1446 }
ca298c88 1447
034be888 1448 return FALSE;
b4071e91 1449}
47d67540 1450
c801d85f 1451//-----------------------------------------------------------------------------
2f2aa628
RR
1452// "value_changed" from m_vAdjust
1453//-----------------------------------------------------------------------------
c801d85f 1454
5e014a0c 1455static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindow *win )
c801d85f 1456{
c50f1fb9 1457 if (g_isIdle)
a2053b27 1458 wxapp_install_idle_handler();
c801d85f 1459
a2053b27 1460 if (g_blockEventsOnDrag) return;
47d67540 1461
a2053b27 1462 if (!win->m_hasVMT) return;
5e014a0c
RR
1463
1464 float diff = adjust->value - win->m_oldVerticalPos;
e380f72b 1465 if (fabs(diff) < 0.2) return;
5e014a0c
RR
1466
1467 win->m_oldVerticalPos = adjust->value;
47d67540 1468
5e014a0c
RR
1469 GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
1470 GtkRange *range = GTK_RANGE( scrolledWindow->vscrollbar );
1471
1472 wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
1473 if (range->scroll_type == GTK_SCROLL_STEP_BACKWARD) command = wxEVT_SCROLLWIN_LINEUP;
1474 else if (range->scroll_type == GTK_SCROLL_STEP_FORWARD) command = wxEVT_SCROLLWIN_LINEDOWN;
1475 else if (range->scroll_type == GTK_SCROLL_PAGE_BACKWARD) command = wxEVT_SCROLLWIN_PAGEUP;
1476 else if (range->scroll_type == GTK_SCROLL_PAGE_FORWARD) command = wxEVT_SCROLLWIN_PAGEDOWN;
1477
5e014a0c 1478 int value = (int)(adjust->value+0.5);
c801d85f 1479
c5b42c87 1480 wxScrollWinEvent event( command, value, wxVERTICAL );
e380f72b
RR
1481 event.SetEventObject( win );
1482 win->GetEventHandler()->ProcessEvent( event );
362c6693 1483}
c801d85f
KB
1484
1485//-----------------------------------------------------------------------------
2f2aa628
RR
1486// "value_changed" from m_hAdjust
1487//-----------------------------------------------------------------------------
c801d85f 1488
5e014a0c 1489static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindow *win )
47d67540 1490{
c50f1fb9 1491 if (g_isIdle)
a2053b27 1492 wxapp_install_idle_handler();
47d67540 1493
a2053b27
RR
1494 if (g_blockEventsOnDrag) return;
1495 if (!win->m_hasVMT) return;
47d67540 1496
5e014a0c 1497 float diff = adjust->value - win->m_oldHorizontalPos;
e380f72b 1498 if (fabs(diff) < 0.2) return;
5e014a0c
RR
1499
1500 win->m_oldHorizontalPos = adjust->value;
8bbe427f 1501
5e014a0c
RR
1502 GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
1503 GtkRange *range = GTK_RANGE( scrolledWindow->hscrollbar );
1504
1505 wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
1506 if (range->scroll_type == GTK_SCROLL_STEP_BACKWARD) command = wxEVT_SCROLLWIN_LINEUP;
1507 else if (range->scroll_type == GTK_SCROLL_STEP_FORWARD) command = wxEVT_SCROLLWIN_LINEDOWN;
1508 else if (range->scroll_type == GTK_SCROLL_PAGE_BACKWARD) command = wxEVT_SCROLLWIN_PAGEUP;
1509 else if (range->scroll_type == GTK_SCROLL_PAGE_FORWARD) command = wxEVT_SCROLLWIN_PAGEDOWN;
1510
5e014a0c 1511 int value = (int)(adjust->value+0.5);
47d67540 1512
c5b42c87 1513 wxScrollWinEvent event( command, value, wxHORIZONTAL );
e380f72b
RR
1514 event.SetEventObject( win );
1515 win->GetEventHandler()->ProcessEvent( event );
362c6693 1516}
c801d85f
KB
1517
1518//-----------------------------------------------------------------------------
2f2aa628
RR
1519// "changed" from m_vAdjust
1520//-----------------------------------------------------------------------------
c801d85f 1521
2f2aa628 1522static void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
c801d85f 1523{
c50f1fb9 1524 if (g_isIdle)
a2053b27 1525 wxapp_install_idle_handler();
c801d85f 1526
a2053b27
RR
1527 if (g_blockEventsOnDrag) return;
1528 if (!win->m_hasVMT) return;
47d67540 1529
c5b42c87 1530 wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
a2053b27 1531 int value = (int)(win->m_vAdjust->value+0.5);
c801d85f 1532
c5b42c87 1533 wxScrollWinEvent event( command, value, wxVERTICAL );
e380f72b
RR
1534 event.SetEventObject( win );
1535 win->GetEventHandler()->ProcessEvent( event );
362c6693 1536}
c801d85f
KB
1537
1538//-----------------------------------------------------------------------------
2f2aa628
RR
1539// "changed" from m_hAdjust
1540//-----------------------------------------------------------------------------
c801d85f 1541
2f2aa628 1542static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
47d67540 1543{
c50f1fb9 1544 if (g_isIdle)
a2053b27 1545 wxapp_install_idle_handler();
47d67540 1546
a2053b27
RR
1547 if (g_blockEventsOnDrag) return;
1548 if (!win->m_hasVMT) return;
47d67540 1549
c5b42c87 1550 wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
a2053b27 1551 int value = (int)(win->m_hAdjust->value+0.5);
47d67540 1552
c5b42c87 1553 wxScrollWinEvent event( command, value, wxHORIZONTAL );
e380f72b
RR
1554 event.SetEventObject( win );
1555 win->GetEventHandler()->ProcessEvent( event );
362c6693 1556}
c801d85f 1557
cb43b372
RR
1558//-----------------------------------------------------------------------------
1559// "button_press_event" from scrollbar
1560//-----------------------------------------------------------------------------
1561
8bbe427f
VZ
1562static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
1563 GdkEventButton *WXUNUSED(gdk_event),
ff8bfdbb 1564 wxWindow *win )
cb43b372 1565{
c50f1fb9 1566 if (g_isIdle)
a2053b27
RR
1567 wxapp_install_idle_handler();
1568
1ecc4d80 1569// don't test here as we can release the mouse while being over
5e014a0c 1570// a different window than the slider
1ecc4d80 1571//
76ed8f8d 1572// if (gdk_event->window != widget->slider) return FALSE;
8bbe427f 1573
f03fc89f 1574 win->SetScrolling( TRUE );
47d67540 1575
e380f72b 1576 return FALSE;
cb43b372
RR
1577}
1578
1579//-----------------------------------------------------------------------------
1580// "button_release_event" from scrollbar
1581//-----------------------------------------------------------------------------
1582
5e0201ea 1583static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget),
8bbe427f 1584 GdkEventButton *WXUNUSED(gdk_event),
ff8bfdbb 1585 wxWindow *win )
cb43b372 1586{
76ed8f8d 1587
1ecc4d80 1588// don't test here as we can release the mouse while being over
5e014a0c 1589// a different window than the slider
76ed8f8d
RR
1590//
1591// if (gdk_event->window != widget->slider) return FALSE;
cb43b372 1592
f03fc89f 1593 win->SetScrolling( FALSE );
47d67540 1594
e380f72b 1595 return FALSE;
cb43b372
RR
1596}
1597
f03fc89f
VZ
1598// ----------------------------------------------------------------------------
1599// this wxWindowBase function is implemented here (in platform-specific file)
1600// because it is static and so couldn't be made virtual
1601// ----------------------------------------------------------------------------
2b07d713 1602
f03fc89f 1603wxWindow *wxWindowBase::FindFocus()
2b07d713 1604{
f03fc89f 1605 return g_focusWindow;
2b07d713 1606}
ca298c88 1607
a2053b27
RR
1608//-----------------------------------------------------------------------------
1609// "realize" from m_widget
1610//-----------------------------------------------------------------------------
1611
5e014a0c 1612/* we cannot set colours and fonts before the widget has
a2053b27
RR
1613 been realized, so we do this directly after realization */
1614
1615static gint
a234a61a 1616gtk_window_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win )
a2053b27 1617{
c50f1fb9 1618 if (g_isIdle)
a2053b27
RR
1619 wxapp_install_idle_handler();
1620
739730ca
RR
1621 if (win->m_delayedFont)
1622 win->SetFont( win->GetFont() );
a2053b27 1623
739730ca
RR
1624 if (win->m_delayedBackgroundColour)
1625 win->SetBackgroundColour( win->GetBackgroundColour() );
a2053b27 1626
739730ca
RR
1627 if (win->m_delayedForegroundColour)
1628 win->SetForegroundColour( win->GetForegroundColour() );
a2053b27 1629
3c679789
RR
1630 wxWindowCreateEvent event( win );
1631 event.SetEventObject( win );
1632 win->GetEventHandler()->ProcessEvent( event );
a2053b27
RR
1633
1634 return FALSE;
1635}
1636
6ca41e57
RR
1637//-----------------------------------------------------------------------------
1638// InsertChild for wxWindow.
1639//-----------------------------------------------------------------------------
1640
b1170810
RR
1641/* Callback for wxWindow. This very strange beast has to be used because
1642 * C++ has no virtual methods in a constructor. We have to emulate a
1643 * virtual function here as wxNotebook requires a different way to insert
1644 * a child in it. I had opted for creating a wxNotebookPage window class
1645 * which would have made this superfluous (such in the MDI window system),
1646 * but no-one was listening to me... */
6ca41e57
RR
1647
1648static void wxInsertChildInWindow( wxWindow* parent, wxWindow* child )
1649{
bf0c00c6
RR
1650 /* the window might have been scrolled already, do we
1651 have to adapt the position */
da048e3d
RR
1652 GtkPizza *pizza = GTK_PIZZA(parent->m_wxwindow);
1653 child->m_x += pizza->xoffset;
1654 child->m_y += pizza->yoffset;
bf0c00c6 1655
da048e3d 1656 gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
a2053b27
RR
1657 GTK_WIDGET(child->m_widget),
1658 child->m_x,
1659 child->m_y,
1660 child->m_width,
1661 child->m_height );
6ca41e57
RR
1662}
1663
bbe0af5b
RR
1664//-----------------------------------------------------------------------------
1665// global functions
1666//-----------------------------------------------------------------------------
1667
1668wxWindow* wxGetActiveWindow()
1669{
f03fc89f 1670 return g_focusWindow;
bbe0af5b
RR
1671}
1672
c801d85f 1673//-----------------------------------------------------------------------------
2f2aa628 1674// wxWindow
c801d85f
KB
1675//-----------------------------------------------------------------------------
1676
f03fc89f 1677IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
c801d85f 1678
68995f26 1679void wxWindow::Init()
c801d85f 1680{
f03fc89f
VZ
1681 // common init
1682 InitBase();
68995f26 1683
f03fc89f 1684 // GTK specific
a2053b27 1685 m_widget = (GtkWidget *) NULL;
e380f72b 1686 m_wxwindow = (GtkWidget *) NULL;
8bbe427f 1687
f03fc89f 1688 // position/size
a2053b27
RR
1689 m_x = 0;
1690 m_y = 0;
1691 m_width = 0;
e380f72b 1692 m_height = 0;
8bbe427f 1693
e380f72b
RR
1694 m_sizeSet = FALSE;
1695 m_hasVMT = FALSE;
1696 m_needParent = TRUE;
31c6b4fc 1697 m_isBeingDeleted = FALSE;
147bc491
RR
1698
1699 m_noExpose = FALSE;
30760ce7
RR
1700 m_nativeSizeEvent = FALSE;
1701
a2053b27 1702 m_hasScrolling = FALSE;
e380f72b 1703 m_isScrolling = FALSE;
f03fc89f 1704
a2053b27 1705 m_hAdjust = (GtkAdjustment*) NULL;
e380f72b 1706 m_vAdjust = (GtkAdjustment*) NULL;
a2053b27 1707 m_oldHorizontalPos = 0.0;
e380f72b 1708 m_oldVerticalPos = 0.0;
8bbe427f 1709
e380f72b 1710 m_resizing = FALSE;
e380f72b 1711 m_widgetStyle = (GtkStyle*) NULL;
8bbe427f 1712
ddb6bc71 1713 m_insertCallback = (wxInsertChildFunction) NULL;
8bbe427f 1714
1ecc4d80 1715 m_isStaticBox = FALSE;
953704c1 1716 m_isRadioButton = FALSE;
54517652 1717 m_isFrame = FALSE;
b292e2f5 1718 m_acceptsFocus = FALSE;
5e014a0c
RR
1719
1720 m_cursor = *wxSTANDARD_CURSOR;
362c6693 1721}
c801d85f 1722
68995f26
VZ
1723wxWindow::wxWindow()
1724{
1725 Init();
1726}
1727
6ca41e57 1728wxWindow::wxWindow( wxWindow *parent, wxWindowID id,
e380f72b
RR
1729 const wxPoint &pos, const wxSize &size,
1730 long style, const wxString &name )
6ca41e57 1731{
68995f26
VZ
1732 Init();
1733
e380f72b 1734 Create( parent, id, pos, size, style, name );
6ca41e57 1735}
8bbe427f 1736
debe6624 1737bool wxWindow::Create( wxWindow *parent, wxWindowID id,
e380f72b
RR
1738 const wxPoint &pos, const wxSize &size,
1739 long style, const wxString &name )
c801d85f 1740{
4dcaf11a
RR
1741 if (!PreCreation( parent, pos, size ) ||
1742 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
1743 {
223d09f6 1744 wxFAIL_MSG( wxT("wxWindow creation failed") );
4dcaf11a
RR
1745 return FALSE;
1746 }
47d67540 1747
ddb6bc71
RR
1748 m_insertCallback = wxInsertChildInWindow;
1749
e380f72b 1750 m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
38c7b3d3 1751 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
ff8bfdbb 1752
2e563988 1753#ifdef __WXDEBUG__
223d09f6 1754 debug_focus_in( m_widget, wxT("wxWindow::m_widget"), name );
2e563988
RR
1755#endif
1756
f03fc89f 1757 GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget);
47d67540 1758
2e563988 1759#ifdef __WXDEBUG__
223d09f6
KB
1760 debug_focus_in( scrolledWindow->hscrollbar, wxT("wxWindow::hsrcollbar"), name );
1761 debug_focus_in( scrolledWindow->vscrollbar, wxT("wxWindow::vsrcollbar"), name );
2e563988
RR
1762#endif
1763
e380f72b
RR
1764 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
1765 scroll_class->scrollbar_spacing = 0;
47d67540 1766
f03fc89f 1767 gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
47d67540 1768
f03fc89f
VZ
1769 m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->hscrollbar) );
1770 m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(scrolledWindow->vscrollbar) );
47d67540 1771
da048e3d 1772 m_wxwindow = gtk_pizza_new();
38c7b3d3 1773
2e563988 1774#ifdef __WXDEBUG__
223d09f6 1775 debug_focus_in( m_wxwindow, wxT("wxWindow::m_wxwindow"), name );
2e563988
RR
1776#endif
1777
034be888 1778 gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
58dea4b0 1779
034be888 1780#if (GTK_MINOR_VERSION > 0)
da048e3d 1781 GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
b292e2f5 1782
f03fc89f 1783 if (HasFlag(wxRAISED_BORDER))
034be888 1784 {
da048e3d 1785 gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_OUT );
034be888 1786 }
f03fc89f 1787 else if (HasFlag(wxSUNKEN_BORDER))
034be888 1788 {
da048e3d 1789 gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_IN );
5e014a0c
RR
1790 }
1791 else if (HasFlag(wxSIMPLE_BORDER))
1792 {
da048e3d 1793 gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_THIN );
034be888
RR
1794 }
1795 else
1796 {
da048e3d 1797 gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_NONE );
034be888 1798 }
f03fc89f
VZ
1799#else // GTK_MINOR_VERSION == 0
1800 GtkViewport *viewport = GTK_VIEWPORT(scrolledWindow->viewport);
b292e2f5 1801
f03fc89f 1802 if (HasFlag(wxRAISED_BORDER))
e380f72b
RR
1803 {
1804 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
1805 }
f03fc89f 1806 else if (HasFlag(wxSUNKEN_BORDER))
e380f72b
RR
1807 {
1808 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
1809 }
1810 else
1811 {
1812 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
1813 }
f03fc89f 1814#endif // GTK_MINOR_VERSION
47d67540 1815
3da17724
RR
1816 GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
1817 m_acceptsFocus = TRUE;
ca298c88 1818
034be888 1819#if (GTK_MINOR_VERSION == 0)
e380f72b
RR
1820 // shut the viewport up
1821 gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1822 gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
f03fc89f 1823#endif // GTK_MINOR_VERSION == 0
e380f72b
RR
1824
1825 // I _really_ don't want scrollbars in the beginning
a2053b27
RR
1826 m_vAdjust->lower = 0.0;
1827 m_vAdjust->upper = 1.0;
1828 m_vAdjust->value = 0.0;
1829 m_vAdjust->step_increment = 1.0;
1830 m_vAdjust->page_increment = 1.0;
1831 m_vAdjust->page_size = 5.0;
1832 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
1833 m_hAdjust->lower = 0.0;
1834 m_hAdjust->upper = 1.0;
1835 m_hAdjust->value = 0.0;
1836 m_hAdjust->step_increment = 1.0;
1837 m_hAdjust->page_increment = 1.0;
1838 m_hAdjust->page_size = 5.0;
1839 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
f03fc89f
VZ
1840
1841 // these handlers block mouse events to any window during scrolling such as
1842 // motion events and prevent GTK and wxWindows from fighting over where the
1843 // slider should be
1844
1845 gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_press_event",
76ed8f8d
RR
1846 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1847
f03fc89f 1848 gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_press_event",
76ed8f8d
RR
1849 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1850
f03fc89f 1851 gtk_signal_connect( GTK_OBJECT(scrolledWindow->vscrollbar), "button_release_event",
76ed8f8d
RR
1852 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
1853
f03fc89f 1854 gtk_signal_connect( GTK_OBJECT(scrolledWindow->hscrollbar), "button_release_event",
76ed8f8d 1855 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
8bbe427f 1856
034be888 1857 // these handlers get notified when screen updates are required either when
76ed8f8d
RR
1858 // scrolling or when the window size (and therefore scrollbar configuration)
1859 // has changed
1860
1861 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
1862 (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
1863 gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
1864 (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
1865
1866 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
1867 (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
1868 gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
1869 (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
1870
f03fc89f 1871 gtk_widget_show( m_wxwindow );
47d67540 1872
f03fc89f
VZ
1873 if (m_parent)
1874 m_parent->DoAddChild( this );
8bbe427f 1875
e380f72b 1876 PostCreation();
8bbe427f 1877
e380f72b 1878 Show( TRUE );
c801d85f 1879
e380f72b 1880 return TRUE;
362c6693 1881}
c801d85f 1882
68dda785 1883wxWindow::~wxWindow()
c801d85f 1884{
31c6b4fc 1885 m_isBeingDeleted = TRUE;
43a18898 1886 m_hasVMT = FALSE;
47d67540 1887
f03fc89f
VZ
1888 if (m_widget)
1889 Show( FALSE );
8bbe427f 1890
a2053b27
RR
1891 DestroyChildren();
1892
f03fc89f
VZ
1893 if (m_parent)
1894 m_parent->RemoveChild( this );
c801d85f 1895
f03fc89f 1896 if (m_widgetStyle)
a2053b27 1897 {
f03fc89f 1898 gtk_style_unref( m_widgetStyle );
c50f1fb9 1899 m_widgetStyle = (GtkStyle*) NULL;
a2053b27 1900 }
c801d85f 1901
f03fc89f 1902 if (m_wxwindow)
a2053b27 1903 {
f03fc89f 1904 gtk_widget_destroy( m_wxwindow );
c50f1fb9 1905 m_wxwindow = (GtkWidget*) NULL;
a2053b27 1906 }
8bbe427f 1907
f03fc89f 1908 if (m_widget)
a2053b27 1909 {
f03fc89f 1910 gtk_widget_destroy( m_widget );
c50f1fb9 1911 m_widget = (GtkWidget*) NULL;
a2053b27 1912 }
362c6693 1913}
c801d85f 1914
4dcaf11a 1915bool wxWindow::PreCreation( wxWindow *parent, const wxPoint &pos, const wxSize &size )
c801d85f 1916{
223d09f6 1917 wxCHECK_MSG( !m_needParent || parent, FALSE, wxT("Need complete parent.") );
8bbe427f 1918
4dcaf11a
RR
1919 /* this turns -1 into 20 so that a minimal window is
1920 visible even although -1,-1 has been given as the
1921 size of the window. the same trick is used in other
1922 ports and should make debugging easier */
f03fc89f
VZ
1923 m_width = WidthDefault(size.x);
1924 m_height = HeightDefault(size.y);
8bbe427f 1925
43a18898
RR
1926 m_x = (int)pos.x;
1927 m_y = (int)pos.y;
8bbe427f 1928
4dcaf11a
RR
1929 /* some reasonable defaults */
1930 if (!parent)
6ca41e57 1931 {
43a18898
RR
1932 if (m_x == -1)
1933 {
1934 m_x = (gdk_screen_width () - m_width) / 2;
1935 if (m_x < 10) m_x = 10;
1936 }
1937 if (m_y == -1)
1938 {
1939 m_y = (gdk_screen_height () - m_height) / 2;
1940 if (m_y < 10) m_y = 10;
1941 }
6ca41e57 1942 }
4dcaf11a
RR
1943
1944 return TRUE;
c801d85f
KB
1945}
1946
68dda785 1947void wxWindow::PostCreation()
c801d85f 1948{
223d09f6 1949 wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
ca298c88 1950
43a18898
RR
1951 if (m_wxwindow)
1952 {
147bc491
RR
1953 if (!m_noExpose)
1954 {
1955 /* these get reported to wxWindows -> wxPaintEvent */
1956 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
1957 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
1958
1959 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
1960 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
1961 }
f7a11f8c 1962
ef47f9b3 1963#if (GTK_MINOR_VERSION > 0)
ed673c6a 1964 /* these are called when the "sunken" or "raised" borders are drawn */
034be888
RR
1965 gtk_signal_connect( GTK_OBJECT(m_widget), "expose_event",
1966 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this );
1967
1968 gtk_signal_connect( GTK_OBJECT(m_widget), "draw",
1969 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this );
ef47f9b3 1970#endif
43a18898 1971 }
47d67540 1972
a2053b27 1973 GtkWidget *connect_widget = GetConnectWidget();
f03fc89f 1974
a2053b27 1975 ConnectWidget( connect_widget );
47d67540 1976
a2053b27
RR
1977 /* we cannot set colours, fonts and cursors before the widget has
1978 been realized, so we do this directly after realization */
1979 gtk_signal_connect( GTK_OBJECT(connect_widget), "realize",
c50f1fb9 1980 GTK_SIGNAL_FUNC(gtk_window_realized_callback), (gpointer) this );
ca298c88 1981
43a18898 1982 m_hasVMT = TRUE;
b4071e91
RR
1983}
1984
1985void wxWindow::ConnectWidget( GtkWidget *widget )
1986{
43a18898
RR
1987 gtk_signal_connect( GTK_OBJECT(widget), "key_press_event",
1988 GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
c801d85f 1989
b666df2c
RR
1990 gtk_signal_connect( GTK_OBJECT(widget), "key_release_event",
1991 GTK_SIGNAL_FUNC(gtk_window_key_release_callback), (gpointer)this );
1992
43a18898
RR
1993 gtk_signal_connect( GTK_OBJECT(widget), "button_press_event",
1994 GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
47d67540 1995
43a18898
RR
1996 gtk_signal_connect( GTK_OBJECT(widget), "button_release_event",
1997 GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
47d67540 1998
43a18898
RR
1999 gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event",
2000 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
47d67540 2001
43a18898
RR
2002 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
2003 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
c801d85f 2004
43a18898
RR
2005 gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event",
2006 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
c801d85f 2007
43a18898
RR
2008 gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event",
2009 GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
47d67540 2010
43a18898
RR
2011 gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event",
2012 GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
362c6693 2013}
c801d85f 2014
68dda785 2015bool wxWindow::Destroy()
c801d85f 2016{
223d09f6 2017 wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
47d67540 2018
43a18898 2019 m_hasVMT = FALSE;
c801d85f 2020
f03fc89f 2021 return wxWindowBase::Destroy();
362c6693 2022}
c801d85f 2023
bfc6fde4 2024void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
c801d85f 2025{
223d09f6
KB
2026 wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
2027 wxASSERT_MSG( (m_parent != NULL), wxT("wxWindow::SetSize requires parent.\n") );
8bbe427f 2028
e27ce4e9 2029 if (m_resizing) return; /* I don't like recursions */
fb1585ae 2030 m_resizing = TRUE;
47d67540 2031
a2053b27 2032 if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */
fb1585ae 2033 {
e27ce4e9 2034 /* don't set the size for children of wxNotebook, just take the values. */
fb1585ae
RR
2035 m_x = x;
2036 m_y = y;
2037 m_width = width;
ba4e3652 2038 m_height = height;
fb1585ae 2039 }
ba4e3652 2040 else
fb1585ae 2041 {
da048e3d 2042 GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow);
bf0c00c6 2043
85ad5eb5 2044 if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
ba4e3652 2045 {
da048e3d
RR
2046 if (x != -1) m_x = x + pizza->xoffset;
2047 if (y != -1) m_y = y + pizza->yoffset;
ba4e3652
RR
2048 if (width != -1) m_width = width;
2049 if (height != -1) m_height = height;
2050 }
2051 else
2052 {
da048e3d
RR
2053 m_x = x + pizza->xoffset;
2054 m_y = y + pizza->yoffset;
ba4e3652
RR
2055 m_width = width;
2056 m_height = height;
2057 }
47d67540 2058
ba4e3652
RR
2059 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
2060 {
2061 if (width == -1) m_width = 80;
2062 }
2063
2064 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
2065 {
2066 if (height == -1) m_height = 26;
2067 }
8bbe427f 2068
ba4e3652
RR
2069 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
2070 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
d3b4d113
RR
2071 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
2072 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
47d67540 2073
a2053b27 2074 int border = 0;
c50f1fb9 2075 int bottom_border = 0;
f03fc89f 2076
29f538ce 2077 if (GTK_WIDGET_CAN_DEFAULT(m_widget))
c50f1fb9
VZ
2078 {
2079 /* the default button has a border around it */
2080 border = 6;
2081 bottom_border = 5;
2082 }
2083
da048e3d 2084 gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow),
c50f1fb9
VZ
2085 m_widget,
2086 m_x-border,
2087 m_y-border,
2088 m_width+2*border,
2089 m_height+border+bottom_border );
54517652 2090 }
6d693bb4 2091
54517652 2092/*
6d693bb4
RR
2093 wxPrintf( "OnSize sent from " );
2094 if (GetClassInfo() && GetClassInfo()->GetClassName())
2095 wxPrintf( GetClassInfo()->GetClassName() );
2096 wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height );
2097*/
2098
30760ce7
RR
2099 if (!m_nativeSizeEvent)
2100 {
2101 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
2102 event.SetEventObject( this );
2103 GetEventHandler()->ProcessEvent( event );
2104 }
6d693bb4 2105
fb1585ae 2106 m_resizing = FALSE;
362c6693 2107}
c801d85f 2108
9390a202
RR
2109void wxWindow::OnInternalIdle()
2110{
9146082c
RR
2111 wxCursor cursor = m_cursor;
2112 if (g_globalCursor.Ok()) cursor = g_globalCursor;
c50f1fb9 2113
f7a11f8c 2114 if (cursor.Ok())
9146082c 2115 {
3017f78d 2116 /* I now set the cursor anew in every OnInternalIdle call
f7a11f8c
RR
2117 as setting the cursor in a parent window also effects the
2118 windows above so that checking for the current cursor is
2119 not possible. */
bf0c00c6 2120
9146082c 2121 if (m_wxwindow)
6a008b33 2122 {
da048e3d 2123 GdkWindow *window = GTK_PIZZA(m_wxwindow)->bin_window;
6a008b33 2124 if (window)
c50f1fb9 2125 gdk_window_set_cursor( window, cursor.GetCursor() );
6a008b33
VZ
2126
2127 if (!g_globalCursor.Ok())
2128 cursor = *wxSTANDARD_CURSOR;
2129
2130 window = m_widget->window;
5e014a0c 2131 if ((window) && !(GTK_WIDGET_NO_WINDOW(m_widget)))
9146082c 2132 gdk_window_set_cursor( window, cursor.GetCursor() );
5e014a0c 2133
6a008b33
VZ
2134 }
2135 else
2136 {
5e014a0c 2137
9146082c 2138 GdkWindow *window = m_widget->window;
5e014a0c 2139 if ((window) && !(GTK_WIDGET_NO_WINDOW(m_widget)))
9146082c 2140 gdk_window_set_cursor( window, cursor.GetCursor() );
5e014a0c 2141
6a008b33 2142 }
9146082c 2143 }
6a008b33 2144
9390a202
RR
2145 UpdateWindowUI();
2146}
2147
f03fc89f 2148void wxWindow::DoGetSize( int *width, int *height ) const
c801d85f 2149{
223d09f6 2150 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2151
fb1585ae
RR
2152 if (width) (*width) = m_width;
2153 if (height) (*height) = m_height;
362c6693 2154}
c801d85f 2155
bfc6fde4 2156void wxWindow::DoSetClientSize( int width, int height )
c801d85f 2157{
223d09f6 2158 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2159
1ecc4d80 2160 if (!m_wxwindow)
c801d85f 2161 {
1ecc4d80 2162 SetSize( width, height );
c801d85f
KB
2163 }
2164 else
2165 {
1ecc4d80
RR
2166 int dw = 0;
2167 int dh = 0;
2168
034be888 2169#if (GTK_MINOR_VERSION == 0)
98d3fdbe
RR
2170 if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
2171 {
324dbfec
RR
2172 if (HasScrolling())
2173 {
2174 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
014b0d06 2175#if 0 // unused - if this is ok, just remove this line (VZ)
324dbfec 2176 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
014b0d06 2177#endif // 0
324dbfec
RR
2178
2179 GtkWidget *viewport = scroll_window->viewport;
2180 GtkStyleClass *viewport_class = viewport->style->klass;
2181
2182 dw += 2 * viewport_class->xthickness;
2183 dh += 2 * viewport_class->ythickness;
2184 }
98d3fdbe
RR
2185 }
2186#else
2187 if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
2188 {
5e014a0c 2189 /* when using GTK 1.2 we set the shadow border size to 2 */
6a008b33 2190 dw += 2 * 2;
98d3fdbe
RR
2191 dh += 2 * 2;
2192 }
5e014a0c
RR
2193 if (HasFlag(wxSIMPLE_BORDER))
2194 {
2195 /* when using GTK 1.2 we set the simple border size to 1 */
2196 dw += 1 * 2;
2197 dh += 1 * 2;
2198 }
034be888
RR
2199#endif
2200
98d3fdbe
RR
2201 if (HasScrolling())
2202 {
034be888
RR
2203/*
2204 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2205 GtkWidget *vscrollbar = scroll_window->vscrollbar;
ca298c88 2206
f03fc89f 2207 we use this instead: range.slider_width = 11 + 2*2pts edge
034be888 2208*/
47d67540 2209
324dbfec
RR
2210 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
2211 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
2212
1ecc4d80
RR
2213 if (scroll_window->vscrollbar_visible)
2214 {
034be888 2215 dw += 15; /* dw += vscrollbar->allocation.width; */
1ecc4d80
RR
2216 dw += scroll_class->scrollbar_spacing;
2217 }
2218
2219 if (scroll_window->hscrollbar_visible)
2220 {
034be888 2221 dh += 15; /* dh += hscrollbar->allocation.height; */
63cc5d9d 2222 dh += scroll_class->scrollbar_spacing;
1ecc4d80
RR
2223 }
2224 }
2225
034be888 2226 SetSize( width+dw, height+dh );
1ecc4d80 2227 }
362c6693 2228}
c801d85f 2229
f03fc89f 2230void wxWindow::DoGetClientSize( int *width, int *height ) const
c801d85f 2231{
223d09f6 2232 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2233
1ecc4d80
RR
2234 if (!m_wxwindow)
2235 {
2236 if (width) (*width) = m_width;
2237 if (height) (*height) = m_height;
c801d85f
KB
2238 }
2239 else
2240 {
1ecc4d80
RR
2241 int dw = 0;
2242 int dh = 0;
2243
034be888 2244#if (GTK_MINOR_VERSION == 0)
98d3fdbe
RR
2245 if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
2246 {
6a008b33
VZ
2247 if (HasScrolling())
2248 {
2249 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
ec6e0a19 2250#if 0 // unused - if this is ok, just remove this line (VZ)
6a008b33 2251 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
ec6e0a19 2252#endif // 0
6a008b33
VZ
2253
2254 GtkWidget *viewport = scroll_window->viewport;
2255 GtkStyleClass *viewport_class = viewport->style->klass;
2256
2257 dw += 2 * viewport_class->xthickness;
2258 dh += 2 * viewport_class->ythickness;
2259 }
98d3fdbe
RR
2260 }
2261#else
2262 if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
2263 {
5e014a0c 2264 /* when using GTK 1.2 we set the shadow border size to 2 */
6a008b33 2265 dw += 2 * 2;
98d3fdbe
RR
2266 dh += 2 * 2;
2267 }
5e014a0c
RR
2268 if (HasFlag(wxSIMPLE_BORDER))
2269 {
2270 /* when using GTK 1.2 we set the simple border size to 1 */
2271 dw += 1 * 2;
2272 dh += 1 * 2;
2273 }
034be888 2274#endif
98d3fdbe
RR
2275 if (HasScrolling())
2276 {
034be888
RR
2277/*
2278 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2279 GtkWidget *vscrollbar = scroll_window->vscrollbar;
ca298c88 2280
f03fc89f 2281 we use this instead: range.slider_width = 11 + 2*2pts edge
034be888 2282*/
1ecc4d80 2283
6a008b33
VZ
2284 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
2285 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
2286
1ecc4d80
RR
2287 if (scroll_window->vscrollbar_visible)
2288 {
034be888 2289 dw += 15; /* dw += vscrollbar->allocation.width; */
1ecc4d80
RR
2290 dw += scroll_class->scrollbar_spacing;
2291 }
2292
2293 if (scroll_window->hscrollbar_visible)
2294 {
034be888 2295 dh += 15; /* dh += hscrollbar->allocation.height; */
1ecc4d80
RR
2296 dh += scroll_class->scrollbar_spacing;
2297 }
6a008b33 2298 }
47d67540 2299
1ecc4d80
RR
2300 if (width) (*width) = m_width - dw;
2301 if (height) (*height) = m_height - dh;
2302 }
362c6693 2303}
c801d85f 2304
f03fc89f 2305void wxWindow::DoGetPosition( int *x, int *y ) const
c801d85f 2306{
223d09f6 2307 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2308
bf0c00c6
RR
2309 int dx = 0;
2310 int dy = 0;
2311 if (m_parent && m_parent->m_wxwindow)
2312 {
da048e3d
RR
2313 GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow);
2314 dx = pizza->xoffset;
2315 dy = pizza->yoffset;
bf0c00c6
RR
2316 }
2317
2318 if (x) (*x) = m_x - dx;
2319 if (y) (*y) = m_y - dy;
362c6693 2320}
c801d85f 2321
dabc0cd5 2322void wxWindow::DoClientToScreen( int *x, int *y ) const
c801d85f 2323{
223d09f6 2324 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2325
a2053b27
RR
2326 if (!m_widget->window) return;
2327
43a18898
RR
2328 GdkWindow *source = (GdkWindow *) NULL;
2329 if (m_wxwindow)
da048e3d 2330 source = GTK_PIZZA(m_wxwindow)->bin_window;
43a18898
RR
2331 else
2332 source = m_widget->window;
47d67540 2333
43a18898
RR
2334 int org_x = 0;
2335 int org_y = 0;
2336 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 2337
43a18898 2338 if (!m_wxwindow)
c801d85f 2339 {
43a18898
RR
2340 if (GTK_WIDGET_NO_WINDOW (m_widget))
2341 {
2342 org_x += m_widget->allocation.x;
2343 org_y += m_widget->allocation.y;
2344 }
362c6693 2345 }
47d67540 2346
43a18898
RR
2347 if (x) *x += org_x;
2348 if (y) *y += org_y;
362c6693 2349}
c801d85f 2350
dabc0cd5 2351void wxWindow::DoScreenToClient( int *x, int *y ) const
c801d85f 2352{
223d09f6 2353 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2354
a2053b27
RR
2355 if (!m_widget->window) return;
2356
1ecc4d80
RR
2357 GdkWindow *source = (GdkWindow *) NULL;
2358 if (m_wxwindow)
da048e3d 2359 source = GTK_PIZZA(m_wxwindow)->bin_window;
1ecc4d80
RR
2360 else
2361 source = m_widget->window;
47d67540 2362
1ecc4d80
RR
2363 int org_x = 0;
2364 int org_y = 0;
2365 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 2366
1ecc4d80 2367 if (!m_wxwindow)
c801d85f 2368 {
1ecc4d80
RR
2369 if (GTK_WIDGET_NO_WINDOW (m_widget))
2370 {
2371 org_x += m_widget->allocation.x;
2372 org_y += m_widget->allocation.y;
2373 }
362c6693 2374 }
47d67540 2375
1ecc4d80
RR
2376 if (x) *x -= org_x;
2377 if (y) *y -= org_y;
362c6693 2378}
c801d85f 2379
f03fc89f 2380bool wxWindow::Show( bool show )
c801d85f 2381{
223d09f6 2382 wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
47d67540 2383
739730ca
RR
2384 if (!wxWindowBase::Show(show))
2385 {
2386 // nothing to do
f03fc89f 2387 return FALSE;
739730ca 2388 }
8bbe427f 2389
f03fc89f
VZ
2390 if (show)
2391 gtk_widget_show( m_widget );
1ecc4d80 2392 else
f03fc89f 2393 gtk_widget_hide( m_widget );
8bbe427f 2394
f03fc89f 2395 return TRUE;
362c6693 2396}
c801d85f 2397
f03fc89f 2398bool wxWindow::Enable( bool enable )
c801d85f 2399{
223d09f6 2400 wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
5e0aa05a 2401
739730ca
RR
2402 if (!wxWindowBase::Enable(enable))
2403 {
2404 // nothing to do
f03fc89f 2405 return FALSE;
739730ca 2406 }
1ecc4d80 2407
f03fc89f
VZ
2408 gtk_widget_set_sensitive( m_widget, enable );
2409 if ( m_wxwindow )
2410 gtk_widget_set_sensitive( m_wxwindow, enable );
ff8bfdbb 2411
f03fc89f 2412 return TRUE;
362c6693 2413}
c801d85f 2414
f03fc89f 2415int wxWindow::GetCharHeight() const
2f2aa628 2416{
223d09f6 2417 wxCHECK_MSG( (m_widget != NULL), 12, wxT("invalid window") );
47d67540 2418
223d09f6 2419 wxCHECK_MSG( m_font.Ok(), 12, wxT("invalid font") );
2f2aa628 2420
f03fc89f
VZ
2421 GdkFont *font = m_font.GetInternalFont( 1.0 );
2422
2423 return font->ascent + font->descent;
362c6693 2424}
c801d85f 2425
f03fc89f 2426int wxWindow::GetCharWidth() const
c33c4050 2427{
223d09f6 2428 wxCHECK_MSG( (m_widget != NULL), 8, wxT("invalid window") );
47d67540 2429
223d09f6 2430 wxCHECK_MSG( m_font.Ok(), 8, wxT("invalid font") );
47d67540 2431
463c1fa1 2432 GdkFont *font = m_font.GetInternalFont( 1.0 );
ff8bfdbb 2433
463c1fa1 2434 return gdk_string_width( font, "H" );
c33c4050
RR
2435}
2436
f03fc89f
VZ
2437void wxWindow::GetTextExtent( const wxString& string,
2438 int *x,
2439 int *y,
2440 int *descent,
2441 int *externalLeading,
2442 const wxFont *theFont ) const
c33c4050 2443{
463c1fa1
RR
2444 wxFont fontToUse = m_font;
2445 if (theFont) fontToUse = *theFont;
47d67540 2446
223d09f6 2447 wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") );
47d67540 2448
463c1fa1 2449 GdkFont *font = fontToUse.GetInternalFont( 1.0 );
05939a81 2450 if (x) (*x) = gdk_string_width( font, string.mbc_str() );
463c1fa1
RR
2451 if (y) (*y) = font->ascent + font->descent;
2452 if (descent) (*descent) = font->descent;
2453 if (externalLeading) (*externalLeading) = 0; // ??
c33c4050
RR
2454}
2455
68dda785 2456void wxWindow::SetFocus()
c801d85f 2457{
223d09f6 2458 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
ff8bfdbb 2459
354aa1e3
RR
2460 if (m_wxwindow)
2461 {
2462 gtk_widget_grab_focus (m_wxwindow);
2463 return;
2464 }
2465
2466 if (m_widget)
c801d85f 2467 {
354aa1e3 2468 if (GTK_WIDGET_CAN_FOCUS(m_widget) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
463c1fa1 2469 {
354aa1e3 2470 gtk_widget_grab_focus (m_widget);
463c1fa1 2471 }
354aa1e3 2472 else if (GTK_IS_CONTAINER(m_widget))
ff8bfdbb 2473 {
354aa1e3 2474 gtk_container_focus( GTK_CONTAINER(m_widget), GTK_DIR_TAB_FORWARD );
ff8bfdbb
VZ
2475 }
2476 else
2477 {
354aa1e3 2478 // ?
ff8bfdbb 2479 }
362c6693 2480 }
362c6693 2481}
c801d85f 2482
b292e2f5
RR
2483bool wxWindow::AcceptsFocus() const
2484{
f03fc89f 2485 return m_acceptsFocus && wxWindowBase::AcceptsFocus();
b292e2f5
RR
2486}
2487
fdb7dadb 2488bool wxWindow::Reparent( wxWindowBase *newParentBase )
463c1fa1 2489{
223d09f6 2490 wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
c50f1fb9 2491
fdb7dadb
VZ
2492 wxWindow *oldParent = m_parent,
2493 *newParent = (wxWindow *)newParentBase;
a2053b27 2494
5fd11f09
RR
2495 wxASSERT( GTK_IS_WIDGET(m_widget) );
2496
f03fc89f
VZ
2497 if ( !wxWindowBase::Reparent(newParent) )
2498 return FALSE;
8bbe427f 2499
5fd11f09
RR
2500 wxASSERT( GTK_IS_WIDGET(m_widget) );
2501
2502 /* prevent GTK from deleting the widget arbitrarily */
2503 gtk_widget_ref( m_widget );
2504
8ce63e9d
RR
2505 if (oldParent)
2506 {
3017f78d 2507 gtk_container_remove( GTK_CONTAINER(m_widget->parent), m_widget );
8ce63e9d 2508 }
c50f1fb9 2509
5fd11f09
RR
2510 wxASSERT( GTK_IS_WIDGET(m_widget) );
2511
8ce63e9d
RR
2512 if (newParent)
2513 {
2514 /* insert GTK representation */
2515 (*(newParent->m_insertCallback))(newParent, this);
2516 }
c50f1fb9 2517
5fd11f09
RR
2518 /* reverse: prevent GTK from deleting the widget arbitrarily */
2519 gtk_widget_unref( m_widget );
2520
f03fc89f 2521 return TRUE;
362c6693 2522}
c801d85f 2523
c50f1fb9 2524void wxWindow::DoAddChild(wxWindow *child)
ddb6bc71 2525{
223d09f6 2526 wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
ddb6bc71 2527
223d09f6 2528 wxASSERT_MSG( (child != NULL), wxT("invalid child window") );
ddb6bc71 2529
223d09f6 2530 wxASSERT_MSG( (m_insertCallback != NULL), wxT("invalid child insertion function") );
c50f1fb9 2531
ddb6bc71
RR
2532 /* add to list */
2533 AddChild( child );
c50f1fb9 2534
ddb6bc71
RR
2535 /* insert GTK representation */
2536 (*m_insertCallback)(this, child);
2537}
2538
68dda785 2539void wxWindow::Raise()
362c6693 2540{
223d09f6 2541 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2542
a2053b27
RR
2543 if (!m_widget->window) return;
2544
f03fc89f 2545 gdk_window_raise( m_widget->window );
362c6693
RR
2546}
2547
68dda785 2548void wxWindow::Lower()
362c6693 2549{
223d09f6 2550 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2551
a2053b27
RR
2552 if (!m_widget->window) return;
2553
f03fc89f 2554 gdk_window_lower( m_widget->window );
362c6693 2555}
c801d85f 2556
f03fc89f 2557bool wxWindow::SetCursor( const wxCursor &cursor )
86b29a61 2558{
223d09f6 2559 wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
86b29a61 2560
5e014a0c 2561 return wxWindowBase::SetCursor( cursor );
362c6693 2562}
c801d85f 2563
85eb36c2 2564void wxWindow::WarpPointer( int x, int y )
4f22cf8d 2565{
223d09f6 2566 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
85eb36c2 2567
ed673c6a
RR
2568 /* we provide this function ourselves as it is
2569 missing in GDK (top of this file) */
2570
2571 GdkWindow *window = (GdkWindow*) NULL;
2572 if (m_wxwindow)
da048e3d 2573 window = GTK_PIZZA(m_wxwindow)->bin_window;
ed673c6a
RR
2574 else
2575 window = GetConnectWidget()->window;
2576
2577 if (window)
2578 gdk_window_warp_pointer( window, x, y );
4f22cf8d
RR
2579}
2580
debe6624 2581void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
c801d85f 2582{
223d09f6 2583 wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
47d67540 2584
a2053b27
RR
2585 if (!m_widget->window) return;
2586
139adb6a 2587 if (eraseBackground && m_wxwindow && m_wxwindow->window)
c801d85f 2588 {
139adb6a
RR
2589 if (rect)
2590 {
da048e3d 2591 gdk_window_clear_area( GTK_PIZZA(m_wxwindow)->bin_window,
139adb6a 2592 rect->x, rect->y,
f234c60c 2593 rect->width, rect->height );
139adb6a
RR
2594 }
2595 else
2596 {
da048e3d 2597 gdk_window_clear( GTK_PIZZA(m_wxwindow)->bin_window );
139adb6a
RR
2598 }
2599 }
ff8bfdbb 2600
1b68e0b5 2601 /* there is no GTK equivalent of "draw only, don't clear" so we
da048e3d 2602 invent our own in the GtkPizza widget */
1b68e0b5 2603
139adb6a
RR
2604 if (!rect)
2605 {
2606 if (m_wxwindow)
e8b04eb3 2607 {
da048e3d
RR
2608 GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
2609 gboolean old_clear = pizza->clear_on_draw;
2610 gtk_pizza_set_clear( pizza, FALSE );
1b68e0b5
RR
2611
2612 gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
f7a11f8c 2613
da048e3d 2614 gtk_pizza_set_clear( pizza, old_clear );
e8b04eb3 2615 }
ff8bfdbb 2616 else
139adb6a 2617 gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
362c6693 2618 }
c801d85f 2619 else
139adb6a 2620 {
1b68e0b5
RR
2621 GdkRectangle gdk_rect;
2622 gdk_rect.x = rect->x;
2623 gdk_rect.y = rect->y;
2624 gdk_rect.width = rect->width;
2625 gdk_rect.height = rect->height;
139adb6a
RR
2626
2627 if (m_wxwindow)
e8b04eb3 2628 {
da048e3d
RR
2629 GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
2630 gboolean old_clear = pizza->clear_on_draw;
2631 gtk_pizza_set_clear( pizza, FALSE );
1b68e0b5
RR
2632
2633 gtk_widget_draw( m_wxwindow, &gdk_rect );
2634
da048e3d 2635 gtk_pizza_set_clear( pizza, old_clear );
e8b04eb3 2636 }
139adb6a
RR
2637 else
2638 gtk_widget_draw( m_widget, &gdk_rect );
2639 }
362c6693 2640}
c801d85f 2641
68dda785 2642void wxWindow::Clear()
c801d85f 2643{
223d09f6 2644 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 2645
a2053b27
RR
2646 if (!m_widget->window) return;
2647
f234c60c
RR
2648 if (m_wxwindow && m_wxwindow->window)
2649 {
2650 gdk_window_clear( m_wxwindow->window );
2651 }
362c6693 2652}
c801d85f 2653
ff8bfdbb 2654#if wxUSE_TOOLTIPS
f03fc89f 2655void wxWindow::DoSetToolTip( wxToolTip *tip )
b1170810 2656{
f03fc89f 2657 wxWindowBase::DoSetToolTip(tip);
ff8bfdbb 2658
f03fc89f
VZ
2659 if (m_tooltip)
2660 m_tooltip->Apply( this );
b1170810
RR
2661}
2662
05939a81 2663void wxWindow::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
b1170810 2664{
dcf924a3 2665 gtk_tooltips_set_tip( tips, GetConnectWidget(), wxConvCurrent->cWX2MB(tip), (gchar*) NULL );
301cd871 2666}
ff8bfdbb 2667#endif // wxUSE_TOOLTIPS
b1170810 2668
f03fc89f 2669bool wxWindow::SetBackgroundColour( const wxColour &colour )
c801d85f 2670{
223d09f6 2671 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
8bbe427f 2672
739730ca
RR
2673 if (!wxWindowBase::SetBackgroundColour(colour))
2674 {
2675 // don't leave if the GTK widget has just
2676 // been realized
2677 if (!m_delayedBackgroundColour) return FALSE;
2678 }
c50f1fb9 2679
ed673c6a
RR
2680 GdkWindow *window = (GdkWindow*) NULL;
2681 if (m_wxwindow)
da048e3d 2682 window = GTK_PIZZA(m_wxwindow)->bin_window;
ed673c6a
RR
2683 else
2684 window = GetConnectWidget()->window;
2685
2686 if (!window)
739730ca
RR
2687 {
2688 // indicate that a new style has been set
c50f1fb9
VZ
2689 // but it couldn't get applied as the
2690 // widget hasn't been realized yet.
2691 m_delayedBackgroundColour = TRUE;
2692
2693 // pretend we have done something
739730ca
RR
2694 return TRUE;
2695 }
ca298c88 2696
ed673c6a 2697 if (m_wxwindow)
3bc755fc 2698 {
a2053b27
RR
2699 /* wxMSW doesn't clear the window here. I don't do that either to
2700 provide compatibility. call Clear() to do the job. */
ca298c88 2701
ed673c6a
RR
2702 m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) );
2703 gdk_window_set_background( window, m_backgroundColour.GetColor() );
3bc755fc 2704 }
8bbe427f 2705
ae0bdb01 2706 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
121a3581 2707 if (sysbg == m_backgroundColour)
ae0bdb01
RR
2708 {
2709 m_backgroundColour = wxNullColour;
2710 ApplyWidgetStyle();
ff8bfdbb
VZ
2711 m_backgroundColour = sysbg;
2712 }
ae0bdb01
RR
2713 else
2714 {
2715 ApplyWidgetStyle();
2716 }
c801d85f 2717
f03fc89f 2718 return TRUE;
6de97a3b
RR
2719}
2720
f03fc89f 2721bool wxWindow::SetForegroundColour( const wxColour &colour )
6de97a3b 2722{
223d09f6 2723 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
8bbe427f 2724
739730ca
RR
2725 if (!wxWindowBase::SetForegroundColour(colour))
2726 {
2727 // don't leave if the GTK widget has just
2728 // been realized
2729 if (!m_delayedForegroundColour) return FALSE;
2730 }
c50f1fb9 2731
ed673c6a
RR
2732 GdkWindow *window = (GdkWindow*) NULL;
2733 if (m_wxwindow)
da048e3d 2734 window = GTK_PIZZA(m_wxwindow)->bin_window;
ed673c6a
RR
2735 else
2736 window = GetConnectWidget()->window;
2737
2738 if (!window)
739730ca
RR
2739 {
2740 // indicate that a new style has been set
c50f1fb9
VZ
2741 // but it couldn't get applied as the
2742 // widget hasn't been realized yet.
2743 m_delayedForegroundColour = TRUE;
2744
2745 // pretend we have done something
739730ca
RR
2746 return TRUE;
2747 }
2b07d713 2748
ae0bdb01 2749 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
2b62ab35 2750 if ( sysbg == m_backgroundColour )
ae0bdb01
RR
2751 {
2752 m_backgroundColour = wxNullColour;
2753 ApplyWidgetStyle();
ff8bfdbb
VZ
2754 m_backgroundColour = sysbg;
2755 }
ae0bdb01
RR
2756 else
2757 {
2758 ApplyWidgetStyle();
2759 }
f03fc89f
VZ
2760
2761 return TRUE;
58614078
RR
2762}
2763
2764GtkStyle *wxWindow::GetWidgetStyle()
2765{
1ecc4d80 2766 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
8bbe427f 2767
f03fc89f 2768 m_widgetStyle = gtk_style_copy( gtk_widget_get_style( m_widget ) );
8bbe427f 2769
1ecc4d80 2770 return m_widgetStyle;
58614078
RR
2771}
2772
2773void wxWindow::SetWidgetStyle()
2774{
1ecc4d80
RR
2775 GtkStyle *style = GetWidgetStyle();
2776
2777 gdk_font_unref( style->font );
2778 style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
2779
2780 if (m_foregroundColour.Ok())
2781 {
2782 m_foregroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2783 style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
2784 style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
2785 style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
2786 }
2787
2788 if (m_backgroundColour.Ok())
2789 {
2790 m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2791 style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2792 style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2793 style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2794 style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2795 style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2796 style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2797 style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2798 style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2799 }
a81258be
RR
2800}
2801
58614078 2802void wxWindow::ApplyWidgetStyle()
a81258be 2803{
6de97a3b
RR
2804}
2805
2259e007
RR
2806//-----------------------------------------------------------------------------
2807// Pop-up menu stuff
2808//-----------------------------------------------------------------------------
2809
2810static void gtk_pop_hide_callback( GtkWidget *WXUNUSED(widget), bool* is_waiting )
2811{
2812 *is_waiting = FALSE;
2813}
2814
30dea054
RR
2815static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
2816{
1ecc4d80 2817 menu->SetInvokingWindow( win );
1987af7e 2818 wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
1ecc4d80
RR
2819 while (node)
2820 {
1987af7e 2821 wxMenuItem *menuitem = node->GetData();
1ecc4d80
RR
2822 if (menuitem->IsSubMenu())
2823 {
ff8bfdbb
VZ
2824 SetInvokingWindow( menuitem->GetSubMenu(), win );
2825 }
1987af7e
VZ
2826
2827 node = node->GetNext();
1ecc4d80 2828 }
362c6693 2829}
30dea054 2830
0c77152e
RR
2831static gint gs_pop_x = 0;
2832static gint gs_pop_y = 0;
2833
a234a61a
VZ
2834static void pop_pos_callback( GtkMenu * WXUNUSED(menu),
2835 gint *x, gint *y,
2836 wxWindow *win )
0c77152e
RR
2837{
2838 win->ClientToScreen( &gs_pop_x, &gs_pop_y );
2839 *x = gs_pop_x;
2840 *y = gs_pop_y;
2841}
2842
a1665b22 2843bool wxWindow::DoPopupMenu( wxMenu *menu, int x, int y )
30dea054 2844{
223d09f6 2845 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
47d67540 2846
223d09f6 2847 wxCHECK_MSG( menu != NULL, FALSE, wxT("invalid popup-menu") );
8bbe427f 2848
1ecc4d80 2849 SetInvokingWindow( menu, this );
ff8bfdbb 2850
631f1bfe
JS
2851 menu->UpdateUI();
2852
0c77152e
RR
2853 gs_pop_x = x;
2854 gs_pop_y = y;
ff8bfdbb 2855
2259e007
RR
2856 bool is_waiting = TRUE;
2857
2858 gtk_signal_connect( GTK_OBJECT(menu->m_menu), "hide",
2859 GTK_SIGNAL_FUNC(gtk_pop_hide_callback), (gpointer)&is_waiting );
2860
1ecc4d80 2861 gtk_menu_popup(
47d67540 2862 GTK_MENU(menu->m_menu),
0c77152e
RR
2863 (GtkWidget *) NULL, // parent menu shell
2864 (GtkWidget *) NULL, // parent menu item
2865 (GtkMenuPositionFunc) pop_pos_callback,
2866 (gpointer) this, // client data
2867 0, // button used to activate it
54517652 2868 gs_timeLastClick // the time of activation
47d67540 2869 );
2259e007 2870
956dbab1
RR
2871 while (is_waiting)
2872 {
2873 while (gtk_events_pending())
2874 gtk_main_iteration();
2875 }
2259e007 2876
1ecc4d80 2877 return TRUE;
30dea054
RR
2878}
2879
06cfab17 2880#if wxUSE_DRAG_AND_DROP
ac57418f 2881
c801d85f
KB
2882void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
2883{
223d09f6 2884 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 2885
1ecc4d80 2886 GtkWidget *dnd_widget = GetConnectWidget();
47d67540 2887
1ecc4d80 2888 if (m_dropTarget) m_dropTarget->UnregisterWidget( dnd_widget );
47d67540 2889
1ecc4d80
RR
2890 if (m_dropTarget) delete m_dropTarget;
2891 m_dropTarget = dropTarget;
47d67540 2892
1ecc4d80 2893 if (m_dropTarget) m_dropTarget->RegisterWidget( dnd_widget );
362c6693 2894}
c801d85f 2895
f03fc89f 2896#endif // wxUSE_DRAG_AND_DROP
ac57418f 2897
68dda785 2898GtkWidget* wxWindow::GetConnectWidget()
e3e65dac 2899{
1ecc4d80
RR
2900 GtkWidget *connect_widget = m_widget;
2901 if (m_wxwindow) connect_widget = m_wxwindow;
47d67540 2902
1ecc4d80 2903 return connect_widget;
e3e65dac 2904}
47d67540 2905
903f689b
RR
2906bool wxWindow::IsOwnGtkWindow( GdkWindow *window )
2907{
ed673c6a 2908 if (m_wxwindow)
da048e3d 2909 return (window == GTK_PIZZA(m_wxwindow)->bin_window);
ed673c6a 2910
1ecc4d80 2911 return (window == m_widget->window);
903f689b
RR
2912}
2913
f03fc89f 2914bool wxWindow::SetFont( const wxFont &font )
c801d85f 2915{
223d09f6 2916 wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
c801d85f 2917
739730ca
RR
2918 if (!wxWindowBase::SetFont(font))
2919 {
2920 // don't leave if the GTK widget has just
2921 // been realized
2922 if (!m_delayedFont) return FALSE;
2923 }
c50f1fb9 2924
ed673c6a
RR
2925 GdkWindow *window = (GdkWindow*) NULL;
2926 if (m_wxwindow)
da048e3d 2927 window = GTK_PIZZA(m_wxwindow)->bin_window;
ed673c6a
RR
2928 else
2929 window = GetConnectWidget()->window;
2930
2931 if (!window)
739730ca
RR
2932 {
2933 // indicate that a new style has been set
c50f1fb9
VZ
2934 // but it couldn't get applied as the
2935 // widget hasn't been realized yet.
2936 m_delayedFont = TRUE;
2937
2938 // pretend we have done something
739730ca
RR
2939 return TRUE;
2940 }
9c288e4d 2941
ae0bdb01 2942 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
f03fc89f 2943 if ( sysbg == m_backgroundColour )
ae0bdb01
RR
2944 {
2945 m_backgroundColour = wxNullColour;
2946 ApplyWidgetStyle();
ff8bfdbb
VZ
2947 m_backgroundColour = sysbg;
2948 }
ae0bdb01
RR
2949 else
2950 {
2951 ApplyWidgetStyle();
2952 }
c801d85f 2953
f03fc89f 2954 return TRUE;
362c6693 2955}
c801d85f 2956
68dda785 2957void wxWindow::CaptureMouse()
c801d85f 2958{
223d09f6 2959 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 2960
223d09f6 2961 wxCHECK_RET( g_captureWindow == NULL, wxT("CaptureMouse called twice") );
47d67540 2962
ed673c6a
RR
2963 GdkWindow *window = (GdkWindow*) NULL;
2964 if (m_wxwindow)
da048e3d 2965 window = GTK_PIZZA(m_wxwindow)->bin_window;
ed673c6a
RR
2966 else
2967 window = GetConnectWidget()->window;
2968
2969 if (!window) return;
c50f1fb9 2970
ed673c6a 2971 gdk_pointer_grab( window, FALSE,
1ecc4d80
RR
2972 (GdkEventMask)
2973 (GDK_BUTTON_PRESS_MASK |
2974 GDK_BUTTON_RELEASE_MASK |
f7a11f8c 2975 GDK_POINTER_MOTION_HINT_MASK |
1ecc4d80 2976 GDK_POINTER_MOTION_MASK),
ff8bfdbb 2977 (GdkWindow *) NULL,
72195a0f 2978 m_cursor.GetCursor(),
ff8bfdbb 2979 GDK_CURRENT_TIME );
72195a0f 2980 g_captureWindow = this;
362c6693 2981}
c801d85f 2982
68dda785 2983void wxWindow::ReleaseMouse()
c801d85f 2984{
223d09f6 2985 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 2986
223d09f6 2987 wxCHECK_RET( g_captureWindow, wxT("ReleaseMouse called twice") );
47d67540 2988
ed673c6a
RR
2989 GdkWindow *window = (GdkWindow*) NULL;
2990 if (m_wxwindow)
da048e3d 2991 window = GTK_PIZZA(m_wxwindow)->bin_window;
ed673c6a
RR
2992 else
2993 window = GetConnectWidget()->window;
2994
2995 if (!window) return;
c50f1fb9 2996
1ecc4d80 2997 gdk_pointer_ungrab ( GDK_CURRENT_TIME );
72195a0f 2998 g_captureWindow = (wxWindow*) NULL;
362c6693 2999}
c801d85f 3000
f03fc89f 3001bool wxWindow::IsRetained() const
c801d85f 3002{
1ecc4d80 3003 return FALSE;
362c6693 3004}
c801d85f 3005
debe6624 3006void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
cb43b372 3007 int range, bool refresh )
c801d85f 3008{
223d09f6 3009 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
8bbe427f 3010
223d09f6 3011 wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
c801d85f 3012
1ecc4d80 3013 m_hasScrolling = TRUE;
47d67540 3014
1ecc4d80 3015 if (orient == wxHORIZONTAL)
cb43b372 3016 {
1ecc4d80
RR
3017 float fpos = (float)pos;
3018 float frange = (float)range;
3019 float fthumb = (float)thumbVisible;
3020 if (fpos > frange-fthumb) fpos = frange-fthumb;
3021 if (fpos < 0.0) fpos = 0.0;
3022
3023 if ((fabs(frange-m_hAdjust->upper) < 0.2) &&
3024 (fabs(fthumb-m_hAdjust->page_size) < 0.2))
3025 {
3026 SetScrollPos( orient, pos, refresh );
3027 return;
3028 }
47d67540 3029
1ecc4d80 3030 m_oldHorizontalPos = fpos;
47d67540 3031
1ecc4d80
RR
3032 m_hAdjust->lower = 0.0;
3033 m_hAdjust->upper = frange;
3034 m_hAdjust->value = fpos;
3035 m_hAdjust->step_increment = 1.0;
3036 m_hAdjust->page_increment = (float)(wxMax(fthumb,0));
3037 m_hAdjust->page_size = fthumb;
cb43b372 3038 }
1ecc4d80
RR
3039 else
3040 {
3041 float fpos = (float)pos;
3042 float frange = (float)range;
3043 float fthumb = (float)thumbVisible;
3044 if (fpos > frange-fthumb) fpos = frange-fthumb;
3045 if (fpos < 0.0) fpos = 0.0;
3046
3047 if ((fabs(frange-m_vAdjust->upper) < 0.2) &&
3048 (fabs(fthumb-m_vAdjust->page_size) < 0.2))
3049 {
3050 SetScrollPos( orient, pos, refresh );
3051 return;
3052 }
47d67540 3053
1ecc4d80 3054 m_oldVerticalPos = fpos;
47d67540 3055
1ecc4d80
RR
3056 m_vAdjust->lower = 0.0;
3057 m_vAdjust->upper = frange;
3058 m_vAdjust->value = fpos;
3059 m_vAdjust->step_increment = 1.0;
3060 m_vAdjust->page_increment = (float)(wxMax(fthumb,0));
3061 m_vAdjust->page_size = fthumb;
3062 }
47d67540 3063
eb082a08
RR
3064 if (orient == wxHORIZONTAL)
3065 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
3066 else
3067 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
362c6693 3068}
c801d85f 3069
debe6624 3070void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
c801d85f 3071{
223d09f6 3072 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
1ecc4d80 3073
223d09f6 3074 wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
1ecc4d80
RR
3075
3076 if (orient == wxHORIZONTAL)
3077 {
3078 float fpos = (float)pos;
3079 if (fpos > m_hAdjust->upper - m_hAdjust->page_size) fpos = m_hAdjust->upper - m_hAdjust->page_size;
3080 if (fpos < 0.0) fpos = 0.0;
3081 m_oldHorizontalPos = fpos;
3082
3083 if (fabs(fpos-m_hAdjust->value) < 0.2) return;
3084 m_hAdjust->value = fpos;
3085 }
3086 else
3087 {
3088 float fpos = (float)pos;
3089 if (fpos > m_vAdjust->upper - m_vAdjust->page_size) fpos = m_vAdjust->upper - m_vAdjust->page_size;
3090 if (fpos < 0.0) fpos = 0.0;
3091 m_oldVerticalPos = fpos;
ff8bfdbb 3092
1ecc4d80
RR
3093 if (fabs(fpos-m_vAdjust->value) < 0.2) return;
3094 m_vAdjust->value = fpos;
3095 }
47d67540 3096
5e014a0c
RR
3097/*
3098 if (!m_isScrolling)
47d67540 3099 {
5e014a0c 3100*/
1ecc4d80
RR
3101 if (m_wxwindow->window)
3102 {
3103 if (orient == wxHORIZONTAL)
3104 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
3105 else
3106 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
3107 }
5e014a0c 3108/*
cb43b372 3109 }
5e014a0c 3110*/
362c6693 3111}
c801d85f 3112
debe6624 3113int wxWindow::GetScrollThumb( int orient ) const
c801d85f 3114{
223d09f6 3115 wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") );
47d67540 3116
223d09f6 3117 wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") );
47d67540 3118
1ecc4d80
RR
3119 if (orient == wxHORIZONTAL)
3120 return (int)(m_hAdjust->page_size+0.5);
3121 else
3122 return (int)(m_vAdjust->page_size+0.5);
362c6693 3123}
c801d85f 3124
debe6624 3125int wxWindow::GetScrollPos( int orient ) const
c801d85f 3126{
223d09f6 3127 wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") );
47d67540 3128
223d09f6 3129 wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") );
c801d85f 3130
1ecc4d80
RR
3131 if (orient == wxHORIZONTAL)
3132 return (int)(m_hAdjust->value+0.5);
3133 else
3134 return (int)(m_vAdjust->value+0.5);
362c6693 3135}
c801d85f 3136
debe6624 3137int wxWindow::GetScrollRange( int orient ) const
c801d85f 3138{
223d09f6 3139 wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") );
47d67540 3140
223d09f6 3141 wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") );
c801d85f 3142
1ecc4d80
RR
3143 if (orient == wxHORIZONTAL)
3144 return (int)(m_hAdjust->upper+0.5);
3145 else
3146 return (int)(m_vAdjust->upper+0.5);
362c6693 3147}
c801d85f 3148
debe6624 3149void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
c801d85f 3150{
223d09f6 3151 wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
47d67540 3152
223d09f6 3153 wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
c801d85f 3154
da048e3d 3155 gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
ed673c6a
RR
3156
3157/*
a2053b27 3158 if (!m_scrollGC)
96d5ab4d 3159 {
a2053b27
RR
3160 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3161 gdk_gc_set_exposures( m_scrollGC, TRUE );
96d5ab4d 3162 }
c50f1fb9 3163
ea5c6ca7
RR
3164 wxNode *node = m_children.First();
3165 while (node)
3166 {
3167 wxWindow *child = (wxWindow*) node->Data();
c50f1fb9
VZ
3168 int sx = 0;
3169 int sy = 0;
3170 child->GetSize( &sx, &sy );
3171 child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
3172 node = node->Next();
ea5c6ca7 3173 }
96d5ab4d 3174
c801d85f
KB
3175 int cw = 0;
3176 int ch = 0;
3177 GetClientSize( &cw, &ch );
c801d85f
KB
3178 int w = cw - abs(dx);
3179 int h = ch - abs(dy);
c50f1fb9 3180
c801d85f
KB
3181 if ((h < 0) || (w < 0))
3182 {
1ecc4d80 3183 Refresh();
362c6693 3184 }
a2053b27 3185 else
c801d85f 3186 {
a2053b27
RR
3187 int s_x = 0;
3188 int s_y = 0;
3189 if (dx < 0) s_x = -dx;
3190 if (dy < 0) s_y = -dy;
3191 int d_x = 0;
3192 int d_y = 0;
3193 if (dx > 0) d_x = dx;
3194 if (dy > 0) d_y = dy;
c801d85f 3195
a2053b27
RR
3196 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
3197 m_wxwindow->window, s_x, s_y, w, h );
c801d85f 3198
a2053b27
RR
3199 wxRect rect;
3200 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3201 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3202 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3203 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
c801d85f 3204
a2053b27
RR
3205 Refresh( TRUE, &rect );
3206 }
ed673c6a 3207*/
c801d85f
KB
3208}
3209
f03fc89f 3210void wxWindow::SetScrolling(bool scroll)
c801d85f 3211{
f03fc89f 3212 m_isScrolling = g_blockEventsOnScroll = scroll;
c801d85f 3213}