]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/window.cpp
Crude hack to fix crash for 8bit displays. Seems to work fine. PLEASE CHECK
[wxWidgets.git] / src / gtk / 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
868a2826
RR
47//-----------------------------------------------------------------------------
48// documentation on internals
49//-----------------------------------------------------------------------------
50
51/*
52 I have been asked several times about writing some documentation about
53 the GTK port of wxWindows, especially its internal structures. Obviously,
54 you cannot understand wxGTK without knowing a little about the GTK, but
47d67540 55 some more information about what the wxWindow, which is the base class
868a2826 56 for all other window classes, does seems required as well.
47d67540 57
868a2826 58 What does wxWindow do? It contains the common interface for the following
e380f72b 59 jobs of its descendants:
47d67540 60
868a2826 61 1) Define the rudimentary behaviour common to all window classes, such as
e380f72b
RR
62 resizing, intercepting user input (so as to make it possible to use these
63 events for special purposes in a derived class), window names etc.
868a2826
RR
64
65 2) Provide the possibility to contain and manage children, if the derived
66 class is allowed to contain children, which holds true for those window
e380f72b 67 classes which do not display a native GTK widget. To name them, these
868a2826 68 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
47d67540 69 work classes are a special case and are handled a bit differently from
e380f72b 70 the rest. The same holds true for the wxNotebook class.
47d67540 71
868a2826
RR
72 3) Provide the possibility to draw into a client area of a window. This,
73 too, only holds true for classes that do not display a native GTK widget
74 as above.
47d67540 75
e380f72b
RR
76 4) Provide the entire mechanism for scrolling widgets. This actual inter-
77 face for this is usually in wxScrolledWindow, but the GTK implementation
868a2826 78 is in this class.
47d67540 79
868a2826
RR
80 5) A multitude of helper or extra methods for special purposes, such as
81 Drag'n'Drop, managing validators etc.
47d67540 82
e380f72b
RR
83 Normally one might expect, that one wxWindows window would always correspond
84 to one GTK widget. Under GTK, there is no such allround widget that has all
868a2826
RR
85 the functionality. Moreover, the GTK defines a client area as a different
86 widget from the actual widget you are handling. Last but not least some
87 special classes (e.g. wxFrame) handle different categories of widgets and
88 still have the possibility to draw something in the client area.
89 It was therefore required to write a special purpose GTK widget, that would
90 represent a client area in the sense of wxWindows capable to do the jobs
91 2), 3) and 4). I have written this class and it resides in win_gtk.c of
92 this directory.
47d67540 93
868a2826 94 All windows must have a widget, with which they interact with other under-
e380f72b 95 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
868a2826 96 thw wxWindow class has a member variable called m_widget which holds a
e380f72b
RR
97 pointer to this widget. When the window class represents a GTK native widget,
98 this is (in most cases) the only GTK widget the class manages. E.g. the
99 wxStatitText class handles only a GtkLabel widget a pointer to which you
100 can find in m_widget (defined in wxWindow)
8bbe427f 101
e380f72b 102 When the class has a client area for drawing into and for containing children
8bbe427f
VZ
103 it has to handle the client area widget (of the type GtkMyFixed, defined in
104 win_gtk.c), but there could be any number of widgets, handled by a class
105 The common rule for all windows is only, that the widget that interacts with
106 the rest of GTK must be referenced in m_widget and all other widgets must be
107 children of this widget on the GTK level. The top-most widget, which also
108 represents the client area, must be in the m_wxwindow field and must be of
e380f72b 109 the type GtkMyFixed.
47d67540 110
868a2826
RR
111 As I said, the window classes that display a GTK native widget only have
112 one widget, so in the case of e.g. the wxButton class m_widget holds a
113 pointer to a GtkButton widget. But windows with client areas (for drawing
114 and children) have a m_widget field that is a pointer to a GtkScrolled-
115 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
116 one is (in the GTK sense) a child of the GtkScrolledWindow.
47d67540 117
868a2826
RR
118 If the m_wxwindow field is set, then all input to this widget is inter-
119 cepted and sent to the wxWindows class. If not, all input to the widget
120 that gets pointed to by m_widget gets intercepted and sent to the class.
121
122*/
123
2e563988
RR
124//-----------------------------------------------------------------------------
125// debug
126//-----------------------------------------------------------------------------
127
128#ifdef __WXDEBUG__
129
130static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget),
131 GdkEvent *WXUNUSED(event),
132 const wxChar *name )
133{
167e3718
VZ
134 // to enable logging of the focus events replace 0 with 1
135#if 0
136 static bool s_done = FALSE;
137 if ( !s_done )
138 {
139 wxLog::AddTraceMask("focus");
140 s_done = TRUE;
141 }
142#endif
143 wxLogTrace(_T("FOCUS NOW AT: %s"), name);
2e563988
RR
144
145 return FALSE;
146}
147
148void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window )
149{
150 wxString tmp = name;
151 tmp += _T(" FROM ");
152 tmp += window;
153
154 wxChar *s = new wxChar[tmp.Length()+1];
155
156 wxStrcpy( s, tmp );
157
158 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
159 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback), (gpointer)s );
160}
161
162#endif
163
b292e2f5 164//-----------------------------------------------------------------------------
034be888 165// data
b292e2f5
RR
166//-----------------------------------------------------------------------------
167
034be888
RR
168extern wxList wxPendingDelete;
169extern bool g_blockEventsOnDrag;
170extern bool g_blockEventsOnScroll;
acfd422a 171extern bool g_isIdle;
034be888
RR
172static bool g_capturing = FALSE;
173static wxWindow *g_focusWindow = (wxWindow*) NULL;
b292e2f5 174
034be888
RR
175/* hack: we need something to pass to gtk_menu_popup, so we store the time of
176 the last click here */
177static guint32 gs_timeLastClick = 0;
ff8bfdbb 178
acfd422a
RR
179//-----------------------------------------------------------------------------
180// idle system
181//-----------------------------------------------------------------------------
182
183extern void wxapp_install_idle_handler();
184extern bool g_isIdle;
185
ef47f9b3
RR
186#if (GTK_MINOR_VERSION > 0)
187
034be888
RR
188//-----------------------------------------------------------------------------
189// local code (see below)
190//-----------------------------------------------------------------------------
b292e2f5 191
034be888 192static void draw_frame( GtkWidget *widget, wxWindow *win )
b292e2f5 193{
034be888 194 if (!win->HasVMT()) return;
b292e2f5 195
034be888
RR
196 int dw = 0;
197 int dh = 0;
ca298c88 198
034be888
RR
199 if (win->m_hasScrolling)
200 {
201 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget);
202 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass );
ff8bfdbb 203
034be888
RR
204/*
205 GtkWidget *hscrollbar = scroll_window->hscrollbar;
206 GtkWidget *vscrollbar = scroll_window->vscrollbar;
ca298c88
RD
207
208 we use this instead: range.slider_width = 11 + 2*2pts edge
034be888 209*/
ff8bfdbb 210
034be888
RR
211 if (scroll_window->vscrollbar_visible)
212 {
213 dw += 15; /* dw += vscrollbar->allocation.width; */
214 dw += scroll_class->scrollbar_spacing;
215 }
b292e2f5 216
034be888
RR
217 if (scroll_window->hscrollbar_visible)
218 {
219 dh += 15; /* dh += hscrollbar->allocation.height; */
220 dw += scroll_class->scrollbar_spacing;
221 }
222 }
ca298c88 223
034be888
RR
224 int dx = 0;
225 int dy = 0;
226 if (GTK_WIDGET_NO_WINDOW (widget))
227 {
228 dx += widget->allocation.x;
229 dy += widget->allocation.y;
230 }
ca298c88 231
034be888
RR
232 if (win->m_windowStyle & wxRAISED_BORDER)
233 {
ca298c88 234 gtk_draw_shadow( widget->style,
034be888
RR
235 widget->window,
236 GTK_STATE_NORMAL,
237 GTK_SHADOW_OUT,
238 dx, dy,
239 win->m_width-dw, win->m_height-dh );
240 return;
ca298c88
RD
241 }
242
034be888
RR
243 if (win->m_windowStyle & wxSUNKEN_BORDER)
244 {
ca298c88 245 gtk_draw_shadow( widget->style,
034be888
RR
246 widget->window,
247 GTK_STATE_NORMAL,
248 GTK_SHADOW_IN,
ca298c88 249 dx, dy,
034be888
RR
250 win->m_width-dw, win->m_height-dh );
251 return;
252 }
b292e2f5
RR
253}
254
c801d85f 255//-----------------------------------------------------------------------------
034be888 256// "expose_event" of m_widget
c801d85f
KB
257//-----------------------------------------------------------------------------
258
034be888
RR
259static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
260{
261 if (gdk_event->count > 0) return;
262 draw_frame( widget, win );
263}
47d67540 264
034be888
RR
265//-----------------------------------------------------------------------------
266// "draw" of m_wxwindow
267//-----------------------------------------------------------------------------
268
269static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindow *win )
270{
271 draw_frame( widget, win );
272}
c801d85f 273
ef47f9b3
RR
274#endif
275
c801d85f 276//-----------------------------------------------------------------------------
034be888 277// "expose_event" of m_wxwindow
c801d85f
KB
278//-----------------------------------------------------------------------------
279
2f2aa628 280static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win )
47d67540 281{
acfd422a
RR
282 if (g_isIdle) wxapp_install_idle_handler();
283
f5e27805 284 if (!win->HasVMT()) return;
47d67540 285
f5e27805
RR
286 win->m_updateRegion.Union( gdk_event->area.x,
287 gdk_event->area.y,
288 gdk_event->area.width,
289 gdk_event->area.height );
47d67540 290
f5e27805 291 if (gdk_event->count > 0) return;
c801d85f 292
d8c83875 293/*
f5e27805
RR
294 printf( "OnExpose from " );
295 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
296 printf( win->GetClassInfo()->GetClassName() );
297 printf( ".\n" );
d8c83875
RR
298*/
299
f5e27805
RR
300 wxPaintEvent event( win->GetId() );
301 event.SetEventObject( win );
302 win->GetEventHandler()->ProcessEvent( event );
47d67540 303
f5e27805 304 win->m_updateRegion.Clear();
362c6693 305}
c801d85f
KB
306
307//-----------------------------------------------------------------------------
034be888 308// "draw" of m_wxwindow
2f2aa628 309//-----------------------------------------------------------------------------
c801d85f 310
2f2aa628 311static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxWindow *win )
47d67540 312{
acfd422a
RR
313 if (g_isIdle) wxapp_install_idle_handler();
314
f5e27805 315 if (!win->HasVMT()) return;
47d67540 316
f5e27805 317 win->m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
47d67540 318
f5e27805
RR
319 wxPaintEvent event( win->GetId() );
320 event.SetEventObject( win );
321 win->GetEventHandler()->ProcessEvent( event );
47d67540 322
f5e27805 323 win->m_updateRegion.Clear();
362c6693 324}
c801d85f
KB
325
326//-----------------------------------------------------------------------------
b292e2f5 327// "key_press_event" from any window
c801d85f 328//-----------------------------------------------------------------------------
c801d85f 329
2f2aa628 330static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
47d67540 331{
acfd422a
RR
332 if (g_isIdle) wxapp_install_idle_handler();
333
f5e27805
RR
334 if (!win->HasVMT()) return FALSE;
335 if (g_blockEventsOnDrag) return FALSE;
c801d85f 336
7be4c594 337/*
1e133b7d 338 wxPrintf( _T("OnKeyPress from ") );
f5e27805 339 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1e133b7d
RR
340 wxPrintf( win->GetClassInfo()->GetClassName() );
341 wxPrintf( _T(".\n") );
7be4c594 342*/
ca298c88 343
f5e27805
RR
344 long key_code = 0;
345 switch (gdk_event->keyval)
c801d85f 346 {
f5e27805 347 case GDK_BackSpace: key_code = WXK_BACK; break;
5664fc32
RR
348 case GDK_ISO_Left_Tab:
349 case GDK_KP_Tab:
f5e27805
RR
350 case GDK_Tab: key_code = WXK_TAB; break;
351 case GDK_Linefeed: key_code = WXK_RETURN; break;
352 case GDK_Clear: key_code = WXK_CLEAR; break;
353 case GDK_Return: key_code = WXK_RETURN; break;
354 case GDK_Pause: key_code = WXK_PAUSE; break;
355 case GDK_Scroll_Lock: key_code = WXK_SCROLL; break;
356 case GDK_Escape: key_code = WXK_ESCAPE; break;
357 case GDK_Delete: key_code = WXK_DELETE; break;
358 case GDK_Home: key_code = WXK_HOME; break;
359 case GDK_Left: key_code = WXK_LEFT; break;
360 case GDK_Up: key_code = WXK_UP; break;
361 case GDK_Right: key_code = WXK_RIGHT; break;
362 case GDK_Down: key_code = WXK_DOWN; break;
363 case GDK_Prior: key_code = WXK_PRIOR; break;
364// case GDK_Page_Up: key_code = WXK_PAGEUP; break;
365 case GDK_Next: key_code = WXK_NEXT; break;
366// case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
367 case GDK_End: key_code = WXK_END; break;
368 case GDK_Begin: key_code = WXK_HOME; break;
369 case GDK_Select: key_code = WXK_SELECT; break;
370 case GDK_Print: key_code = WXK_PRINT; break;
371 case GDK_Execute: key_code = WXK_EXECUTE; break;
372 case GDK_Insert: key_code = WXK_INSERT; break;
373 case GDK_Num_Lock: key_code = WXK_NUMLOCK; break;
f5e27805
RR
374 case GDK_KP_Enter: key_code = WXK_RETURN; break;
375 case GDK_KP_Home: key_code = WXK_HOME; break;
376 case GDK_KP_Left: key_code = WXK_LEFT; break;
377 case GDK_KP_Up: key_code = WXK_UP; break;
378 case GDK_KP_Right: key_code = WXK_RIGHT; break;
379 case GDK_KP_Down: key_code = WXK_DOWN; break;
380 case GDK_KP_Prior: key_code = WXK_PRIOR; break;
381// case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
382 case GDK_KP_Next: key_code = WXK_NEXT; break;
383// case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
384 case GDK_KP_End: key_code = WXK_END; break;
385 case GDK_KP_Begin: key_code = WXK_HOME; break;
386 case GDK_KP_Insert: key_code = WXK_INSERT; break;
387 case GDK_KP_Delete: key_code = WXK_DELETE; break;
388 case GDK_KP_Multiply: key_code = WXK_MULTIPLY; break;
389 case GDK_KP_Add: key_code = WXK_ADD; break;
390 case GDK_KP_Separator: key_code = WXK_SEPARATOR; break;
391 case GDK_KP_Subtract: key_code = WXK_SUBTRACT; break;
392 case GDK_KP_Decimal: key_code = WXK_DECIMAL; break;
393 case GDK_KP_Divide: key_code = WXK_DIVIDE; break;
394 case GDK_KP_0: key_code = WXK_NUMPAD0; break;
395 case GDK_KP_1: key_code = WXK_NUMPAD1; break;
396 case GDK_KP_2: key_code = WXK_NUMPAD2; break;
397 case GDK_KP_3: key_code = WXK_NUMPAD3; break;
398 case GDK_KP_4: key_code = WXK_NUMPAD4; break;
399 case GDK_KP_5: key_code = WXK_NUMPAD5; break;
400 case GDK_KP_6: key_code = WXK_NUMPAD6; break;
401 case GDK_KP_7: key_code = WXK_NUMPAD7; break;
402 case GDK_KP_8: key_code = WXK_NUMPAD7; break;
403 case GDK_KP_9: key_code = WXK_NUMPAD9; break;
404 case GDK_F1: key_code = WXK_F1; break;
405 case GDK_F2: key_code = WXK_F2; break;
406 case GDK_F3: key_code = WXK_F3; break;
407 case GDK_F4: key_code = WXK_F4; break;
408 case GDK_F5: key_code = WXK_F5; break;
409 case GDK_F6: key_code = WXK_F6; break;
410 case GDK_F7: key_code = WXK_F7; break;
411 case GDK_F8: key_code = WXK_F8; break;
412 case GDK_F9: key_code = WXK_F9; break;
413 case GDK_F10: key_code = WXK_F10; break;
414 case GDK_F11: key_code = WXK_F11; break;
415 case GDK_F12: key_code = WXK_F12; break;
416 default:
417 {
418 if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF))
419 key_code = gdk_event->keyval;
420 }
362c6693 421 }
c801d85f 422
f5e27805 423 if (!key_code) return FALSE;
47d67540 424
b666df2c 425 wxKeyEvent event( wxEVT_KEY_DOWN );
f5e27805
RR
426 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
427 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
428 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
429 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
430 event.m_keyCode = key_code;
431 event.m_x = 0;
432 event.m_y = 0;
433 event.SetEventObject( win );
47d67540 434
f5e27805 435 bool ret = win->GetEventHandler()->ProcessEvent( event );
47d67540 436
f5e27805 437 if (!ret)
47d67540 438 {
f5e27805
RR
439 wxWindow *ancestor = win;
440 while (ancestor)
441 {
442 int command = ancestor->GetAcceleratorTable()->GetCommand( event );
443 if (command != -1)
444 {
445 wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
446 ret = ancestor->GetEventHandler()->ProcessEvent( command_event );
447 break;
448 }
449 ancestor = ancestor->GetParent();
450 }
bcf1fa6b 451 }
ff8bfdbb 452
b292e2f5 453 // win is a control: tab can be propagated up
ca298c88 454 if ( (!ret) &&
5664fc32
RR
455 ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) &&
456 ((win->m_windowStyle & wxTE_PROCESS_TAB) == 0))
b292e2f5
RR
457 {
458 wxNavigationKeyEvent new_event;
b98d804b 459 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
5664fc32 460 new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
ca298c88 461 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
b98d804b 462 new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
b292e2f5 463 new_event.SetCurrentFocus( win );
ff8bfdbb 464 ret = win->GetEventHandler()->ProcessEvent( new_event );
b292e2f5 465 }
ff8bfdbb 466
ca298c88 467 if ( (!ret) &&
b98d804b
RR
468 (gdk_event->keyval == GDK_Escape) )
469 {
470 wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
471 new_event.SetEventObject( win );
472 ret = win->GetEventHandler()->ProcessEvent( new_event );
473 }
ca298c88 474
b292e2f5 475/*
b98d804b
RR
476 Damn, I forgot why this didn't work, but it didn't work.
477
b292e2f5
RR
478 // win is a panel: up can be propagated to the panel
479 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
480 (gdk_event->keyval == GDK_Up))
481 {
482 win->m_parent->SetFocus();
ff8bfdbb 483 ret = TRUE;
b292e2f5 484 }
ff8bfdbb 485
b292e2f5 486 // win is a panel: left/right can be propagated to the panel
ff8bfdbb
VZ
487 if ((!ret) && (win->m_wxwindow) &&
488 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
b292e2f5
RR
489 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
490 {
491 wxNavigationKeyEvent new_event;
492 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
493 new_event.SetCurrentFocus( win );
ff8bfdbb 494 ret = win->GetEventHandler()->ProcessEvent( new_event );
b292e2f5
RR
495 }
496*/
ff8bfdbb 497
f5e27805
RR
498 if (ret)
499 {
b292e2f5 500 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
034be888 501 return TRUE;
f5e27805 502 }
47d67540 503
034be888 504 return FALSE;
362c6693 505}
c801d85f 506
b666df2c
RR
507//-----------------------------------------------------------------------------
508// "key_release_event" from any window
509//-----------------------------------------------------------------------------
510
511static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
512{
acfd422a
RR
513 if (g_isIdle) wxapp_install_idle_handler();
514
b666df2c
RR
515 if (!win->HasVMT()) return FALSE;
516 if (g_blockEventsOnDrag) return FALSE;
517
518/*
519 printf( "OnKeyRelease from " );
520 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
521 printf( win->GetClassInfo()->GetClassName() );
522 printf( ".\n" );
523*/
524
525 long key_code = 0;
526 switch (gdk_event->keyval)
527 {
528 case GDK_BackSpace: key_code = WXK_BACK; break;
5664fc32
RR
529 case GDK_ISO_Left_Tab:
530 case GDK_KP_Tab:
b666df2c
RR
531 case GDK_Tab: key_code = WXK_TAB; break;
532 case GDK_Linefeed: key_code = WXK_RETURN; break;
533 case GDK_Clear: key_code = WXK_CLEAR; break;
534 case GDK_Return: key_code = WXK_RETURN; break;
535 case GDK_Pause: key_code = WXK_PAUSE; break;
536 case GDK_Scroll_Lock: key_code = WXK_SCROLL; break;
537 case GDK_Escape: key_code = WXK_ESCAPE; break;
538 case GDK_Delete: key_code = WXK_DELETE; break;
539 case GDK_Home: key_code = WXK_HOME; break;
540 case GDK_Left: key_code = WXK_LEFT; break;
541 case GDK_Up: key_code = WXK_UP; break;
542 case GDK_Right: key_code = WXK_RIGHT; break;
543 case GDK_Down: key_code = WXK_DOWN; break;
544 case GDK_Prior: key_code = WXK_PRIOR; break;
545// case GDK_Page_Up: key_code = WXK_PAGEUP; break;
546 case GDK_Next: key_code = WXK_NEXT; break;
547// case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
548 case GDK_End: key_code = WXK_END; break;
549 case GDK_Begin: key_code = WXK_HOME; break;
550 case GDK_Select: key_code = WXK_SELECT; break;
551 case GDK_Print: key_code = WXK_PRINT; break;
552 case GDK_Execute: key_code = WXK_EXECUTE; break;
553 case GDK_Insert: key_code = WXK_INSERT; break;
554 case GDK_Num_Lock: key_code = WXK_NUMLOCK; break;
b666df2c
RR
555 case GDK_KP_Enter: key_code = WXK_RETURN; break;
556 case GDK_KP_Home: key_code = WXK_HOME; break;
557 case GDK_KP_Left: key_code = WXK_LEFT; break;
558 case GDK_KP_Up: key_code = WXK_UP; break;
559 case GDK_KP_Right: key_code = WXK_RIGHT; break;
560 case GDK_KP_Down: key_code = WXK_DOWN; break;
561 case GDK_KP_Prior: key_code = WXK_PRIOR; break;
562// case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
563 case GDK_KP_Next: key_code = WXK_NEXT; break;
564// case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
565 case GDK_KP_End: key_code = WXK_END; break;
566 case GDK_KP_Begin: key_code = WXK_HOME; break;
567 case GDK_KP_Insert: key_code = WXK_INSERT; break;
568 case GDK_KP_Delete: key_code = WXK_DELETE; break;
569 case GDK_KP_Multiply: key_code = WXK_MULTIPLY; break;
570 case GDK_KP_Add: key_code = WXK_ADD; break;
571 case GDK_KP_Separator: key_code = WXK_SEPARATOR; break;
572 case GDK_KP_Subtract: key_code = WXK_SUBTRACT; break;
573 case GDK_KP_Decimal: key_code = WXK_DECIMAL; break;
574 case GDK_KP_Divide: key_code = WXK_DIVIDE; break;
575 case GDK_KP_0: key_code = WXK_NUMPAD0; break;
576 case GDK_KP_1: key_code = WXK_NUMPAD1; break;
577 case GDK_KP_2: key_code = WXK_NUMPAD2; break;
578 case GDK_KP_3: key_code = WXK_NUMPAD3; break;
579 case GDK_KP_4: key_code = WXK_NUMPAD4; break;
580 case GDK_KP_5: key_code = WXK_NUMPAD5; break;
581 case GDK_KP_6: key_code = WXK_NUMPAD6; break;
582 case GDK_KP_7: key_code = WXK_NUMPAD7; break;
583 case GDK_KP_8: key_code = WXK_NUMPAD7; break;
584 case GDK_KP_9: key_code = WXK_NUMPAD9; break;
585 case GDK_F1: key_code = WXK_F1; break;
586 case GDK_F2: key_code = WXK_F2; break;
587 case GDK_F3: key_code = WXK_F3; break;
588 case GDK_F4: key_code = WXK_F4; break;
589 case GDK_F5: key_code = WXK_F5; break;
590 case GDK_F6: key_code = WXK_F6; break;
591 case GDK_F7: key_code = WXK_F7; break;
592 case GDK_F8: key_code = WXK_F8; break;
593 case GDK_F9: key_code = WXK_F9; break;
594 case GDK_F10: key_code = WXK_F10; break;
595 case GDK_F11: key_code = WXK_F11; break;
596 case GDK_F12: key_code = WXK_F12; break;
597 default:
598 {
599 if ((gdk_event->keyval >= 0x20) && (gdk_event->keyval <= 0xFF))
600 key_code = gdk_event->keyval;
601 }
602 }
603
604 if (!key_code) return FALSE;
605
606 wxKeyEvent event( wxEVT_KEY_UP );
607 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
608 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
609 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
610 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
611 event.m_keyCode = key_code;
612 event.m_x = 0;
613 event.m_y = 0;
614 event.SetEventObject( win );
615
034be888 616 if (win->GetEventHandler()->ProcessEvent( event ))
b666df2c 617 {
b98d804b 618 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_release_event" );
034be888 619 return TRUE;
b666df2c
RR
620 }
621
034be888 622 return FALSE;
b666df2c
RR
623}
624
c801d85f 625//-----------------------------------------------------------------------------
2f2aa628
RR
626// "button_press_event"
627//-----------------------------------------------------------------------------
c801d85f 628
2f2aa628 629static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
903f689b 630{
acfd422a
RR
631 if (g_isIdle) wxapp_install_idle_handler();
632
1e133b7d
RR
633/*
634 wxPrintf( _T("1) OnButtonPress from ") );
635 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
636 wxPrintf( win->GetClassInfo()->GetClassName() );
637 wxPrintf( _T(".\n") );
638*/
ca298c88 639
034be888 640 if (!win->HasVMT()) return FALSE;
f5e27805 641 if (g_blockEventsOnDrag) return TRUE;
76ed8f8d 642 if (g_blockEventsOnScroll) return TRUE;
c801d85f 643
034be888
RR
644 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
645
f5e27805 646 if (win->m_wxwindow)
c801d85f 647 {
f5e27805
RR
648 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow) && !GTK_WIDGET_HAS_FOCUS (win->m_wxwindow) )
649 {
650 gtk_widget_grab_focus (win->m_wxwindow);
47d67540 651
c801d85f 652/*
1e133b7d 653 wxPrintf( _T("GrabFocus from ") );
f5e27805 654 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1e133b7d
RR
655 wxPrintf( win->GetClassInfo()->GetClassName() );
656 wxPrintf( _T(".\n") );
c801d85f 657*/
47d67540 658
f5e27805 659 }
1e133b7d
RR
660/*
661 else
662 {
663 wxPrintf( _T("No GrabFocus from ") );
664 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
665 wxPrintf( win->GetClassInfo()->GetClassName() );
666 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
667 wxPrintf( _T(" because it already has") );
668 wxPrintf( _T(".\n") );
669 }
670*/
362c6693 671 }
47d67540 672
8429bec1 673/*
1e133b7d 674 wxPrintf( _T("2) OnButtonPress from ") );
f5e27805 675 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1e133b7d
RR
676 wxPrintf( win->GetClassInfo()->GetClassName() );
677 wxPrintf( _T(".\n") );
8429bec1 678*/
30dea054 679
f5e27805 680 wxEventType event_type = wxEVT_LEFT_DOWN;
47d67540 681
f5e27805 682 if (gdk_event->button == 1)
c801d85f 683 {
f5e27805
RR
684 switch (gdk_event->type)
685 {
686 case GDK_BUTTON_PRESS: event_type = wxEVT_LEFT_DOWN; break;
687 case GDK_2BUTTON_PRESS: event_type = wxEVT_LEFT_DCLICK; break;
688 default: break;
689 }
362c6693 690 }
f5e27805 691 else if (gdk_event->button == 2)
c801d85f 692 {
f5e27805
RR
693 switch (gdk_event->type)
694 {
695 case GDK_BUTTON_PRESS: event_type = wxEVT_MIDDLE_DOWN; break;
696 case GDK_2BUTTON_PRESS: event_type = wxEVT_MIDDLE_DCLICK; break;
697 default: break;
698 }
362c6693 699 }
f5e27805 700 else if (gdk_event->button == 3)
c801d85f 701 {
f5e27805
RR
702 switch (gdk_event->type)
703 {
704 case GDK_BUTTON_PRESS: event_type = wxEVT_RIGHT_DOWN; break;
705 case GDK_2BUTTON_PRESS: event_type = wxEVT_RIGHT_DCLICK; break;
706 default: break;
707 }
362c6693 708 }
47d67540 709
f5e27805
RR
710 wxMouseEvent event( event_type );
711 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
712 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
713 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
714 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
715 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
716 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
717 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
47d67540 718
f5e27805
RR
719 event.m_x = (long)gdk_event->x;
720 event.m_y = (long)gdk_event->y;
47d67540 721
f5e27805
RR
722 // Some control don't have their own X window and thus cannot get
723 // any events.
47d67540 724
f5e27805 725 if (!g_capturing)
2f2aa628 726 {
db1b4961 727 wxNode *node = win->GetChildren().First();
f5e27805
RR
728 while (node)
729 {
730 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb
VZ
731
732 if (child->m_isStaticBox)
733 {
734 // wxStaticBox is transparent in the box itself
735 int x = event.m_x;
736 int y = event.m_y;
737 int xx1 = child->m_x;
738 int yy1 = child->m_y;
739 int xx2 = child->m_x + child->m_width;
740 int yy2 = child->m_x + child->m_height;
741
742 // left
743 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
744 // right
745 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
746 // top
747 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
748 // bottom
749 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
750 {
1ecc4d80
RR
751 win = child;
752 event.m_x -= child->m_x;
753 event.m_y -= child->m_y;
754 break;
ff8bfdbb
VZ
755 }
756
757 }
758 else
759 {
1ecc4d80 760 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
ff8bfdbb 761 (child->m_x <= event.m_x) &&
1ecc4d80
RR
762 (child->m_y <= event.m_y) &&
763 (child->m_x+child->m_width >= event.m_x) &&
764 (child->m_y+child->m_height >= event.m_y))
765 {
766 win = child;
767 event.m_x -= child->m_x;
768 event.m_y -= child->m_y;
769 break;
ff8bfdbb 770 }
f5e27805
RR
771 }
772 node = node->Next();
773 }
2f2aa628 774 }
ff8bfdbb 775
f5e27805 776 event.SetEventObject( win );
47d67540 777
f5e27805 778 gs_timeLastClick = gdk_event->time;
47d67540 779
f5e27805 780 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 781 {
f5e27805 782 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_press_event" );
034be888
RR
783 return TRUE;
784 }
47d67540 785
034be888 786 return FALSE;
362c6693 787}
c801d85f
KB
788
789//-----------------------------------------------------------------------------
97b3455a 790// "button_release_event"
2f2aa628 791//-----------------------------------------------------------------------------
c801d85f 792
2f2aa628 793static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
47d67540 794{
acfd422a
RR
795 if (g_isIdle) wxapp_install_idle_handler();
796
034be888
RR
797 if (!win->HasVMT()) return FALSE;
798 if (g_blockEventsOnDrag) return FALSE;
799 if (g_blockEventsOnScroll) return FALSE;
c801d85f 800
034be888 801 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
47d67540 802
c801d85f 803/*
f5e27805
RR
804 printf( "OnButtonRelease from " );
805 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
806 printf( win->GetClassInfo()->GetClassName() );
807 printf( ".\n" );
c801d85f 808*/
47d67540 809
f5e27805 810 wxEventType event_type = wxEVT_NULL;
47d67540 811
f5e27805
RR
812 switch (gdk_event->button)
813 {
814 case 1: event_type = wxEVT_LEFT_UP; break;
815 case 2: event_type = wxEVT_MIDDLE_UP; break;
816 case 3: event_type = wxEVT_RIGHT_UP; break;
817 }
47d67540 818
f5e27805
RR
819 wxMouseEvent event( event_type );
820 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
821 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
822 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
823 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
824 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
825 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
826 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
827 event.m_x = (long)gdk_event->x;
828 event.m_y = (long)gdk_event->y;
829
830 // Some control don't have their own X window and thus cannot get
831 // any events.
832
833 if (!g_capturing)
2f2aa628 834 {
db1b4961 835 wxNode *node = win->GetChildren().First();
f5e27805
RR
836 while (node)
837 {
838 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb
VZ
839
840 if (child->m_isStaticBox)
841 {
842 // wxStaticBox is transparent in the box itself
843 int x = event.m_x;
844 int y = event.m_y;
845 int xx1 = child->m_x;
846 int yy1 = child->m_y;
847 int xx2 = child->m_x + child->m_width;
848 int yy2 = child->m_x + child->m_height;
849
850 // left
851 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
852 // right
853 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
854 // top
855 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
856 // bottom
857 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
858 {
1ecc4d80
RR
859 win = child;
860 event.m_x -= child->m_x;
861 event.m_y -= child->m_y;
862 break;
ff8bfdbb
VZ
863 }
864
865 }
866 else
867 {
1ecc4d80 868 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
ff8bfdbb 869 (child->m_x <= event.m_x) &&
1ecc4d80
RR
870 (child->m_y <= event.m_y) &&
871 (child->m_x+child->m_width >= event.m_x) &&
872 (child->m_y+child->m_height >= event.m_y))
873 {
874 win = child;
875 event.m_x -= child->m_x;
876 event.m_y -= child->m_y;
877 break;
ff8bfdbb 878 }
f5e27805
RR
879 }
880 node = node->Next();
881 }
2f2aa628 882 }
47d67540 883
f5e27805 884 event.SetEventObject( win );
47d67540 885
f5e27805 886 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 887 {
f5e27805 888 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "button_release_event" );
034be888
RR
889 return TRUE;
890 }
47d67540 891
034be888 892 return FALSE;
362c6693 893}
c801d85f
KB
894
895//-----------------------------------------------------------------------------
2f2aa628
RR
896// "motion_notify_event"
897//-----------------------------------------------------------------------------
c801d85f 898
2f2aa628 899static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
47d67540 900{
acfd422a
RR
901 if (g_isIdle) wxapp_install_idle_handler();
902
034be888
RR
903 if (!win->HasVMT()) return FALSE;
904 if (g_blockEventsOnDrag) return FALSE;
905 if (g_blockEventsOnScroll) return FALSE;
906
907 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
908
ff8bfdbb 909 if (gdk_event->is_hint)
aae24d21
RR
910 {
911 int x = 0;
912 int y = 0;
913 GdkModifierType state;
914 gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
915 gdk_event->x = x;
916 gdk_event->y = y;
917 gdk_event->state = state;
918 }
ff8bfdbb 919
c801d85f 920/*
e380f72b
RR
921 printf( "OnMotion from " );
922 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
923 printf( win->GetClassInfo()->GetClassName() );
924 printf( ".\n" );
aae24d21 925*/
47d67540 926
e380f72b
RR
927 wxMouseEvent event( wxEVT_MOTION );
928 event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
929 event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
930 event.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
931 event.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
932 event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK);
933 event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK);
934 event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK);
935
936 event.m_x = (long)gdk_event->x;
937 event.m_y = (long)gdk_event->y;
938
939 // Some control don't have their own X window and thus cannot get
940 // any events.
941
942 if (!g_capturing)
2f2aa628 943 {
db1b4961 944 wxNode *node = win->GetChildren().First();
e380f72b
RR
945 while (node)
946 {
947 wxWindow *child = (wxWindow*)node->Data();
ff8bfdbb
VZ
948
949 if (child->m_isStaticBox)
950 {
951 // wxStaticBox is transparent in the box itself
952 int x = event.m_x;
953 int y = event.m_y;
954 int xx1 = child->m_x;
955 int yy1 = child->m_y;
956 int xx2 = child->m_x + child->m_width;
957 int yy2 = child->m_x + child->m_height;
958
959 // left
960 if (((x >= xx1) && (x <= xx1+10) && (y >= yy1) && (y <= yy2)) ||
961 // right
962 ((x >= xx2-10) && (x <= xx2) && (y >= yy1) && (y <= yy2)) ||
963 // top
964 ((x >= xx1) && (x <= xx2) && (y >= yy1) && (y <= yy1+10)) ||
965 // bottom
966 ((x >= xx1) && (x <= xx2) && (y >= yy2-1) && (y <= yy2)))
967 {
1ecc4d80
RR
968 win = child;
969 event.m_x -= child->m_x;
970 event.m_y -= child->m_y;
971 break;
ff8bfdbb
VZ
972 }
973
974 }
975 else
976 {
1ecc4d80 977 if ((child->m_wxwindow == (GtkWidget*) NULL) &&
ff8bfdbb 978 (child->m_x <= event.m_x) &&
1ecc4d80
RR
979 (child->m_y <= event.m_y) &&
980 (child->m_x+child->m_width >= event.m_x) &&
981 (child->m_y+child->m_height >= event.m_y))
982 {
983 win = child;
984 event.m_x -= child->m_x;
985 event.m_y -= child->m_y;
986 break;
ff8bfdbb 987 }
e380f72b
RR
988 }
989 node = node->Next();
990 }
2f2aa628 991 }
47d67540 992
e380f72b 993 event.SetEventObject( win );
47d67540 994
e380f72b 995 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 996 {
e380f72b 997 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "motion_notify_event" );
034be888
RR
998 return TRUE;
999 }
47d67540 1000
034be888 1001 return FALSE;
362c6693 1002}
c801d85f
KB
1003
1004//-----------------------------------------------------------------------------
2f2aa628
RR
1005// "focus_in_event"
1006//-----------------------------------------------------------------------------
c801d85f 1007
2f2aa628 1008static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 1009{
acfd422a
RR
1010 if (g_isIdle) wxapp_install_idle_handler();
1011
034be888
RR
1012 if (!win->HasVMT()) return FALSE;
1013 if (g_blockEventsOnDrag) return FALSE;
ff8bfdbb 1014
b292e2f5 1015 g_focusWindow = win;
ff8bfdbb 1016
e380f72b 1017 if (win->m_wxwindow)
c801d85f 1018 {
e380f72b
RR
1019 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
1020 {
1021 GTK_WIDGET_SET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
47d67540 1022/*
e380f72b
RR
1023 printf( "SetFocus flag from " );
1024 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1025 printf( win->GetClassInfo()->GetClassName() );
1026 printf( ".\n" );
c801d85f 1027*/
e380f72b 1028 }
362c6693 1029 }
47d67540 1030
47d67540 1031
c801d85f 1032/*
1e133b7d 1033 wxPrintf( _T("OnSetFocus from ") );
e380f72b 1034 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1e133b7d
RR
1035 wxPrintf( win->GetClassInfo()->GetClassName() );
1036 wxPrintf( _T(" ") );
1037 wxPrintf( win->GetLabel() );
1038 wxPrintf( _T(".\n") );
c801d85f 1039*/
47d67540 1040
e380f72b
RR
1041 wxFocusEvent event( wxEVT_SET_FOCUS, win->GetId() );
1042 event.SetEventObject( win );
47d67540 1043
e380f72b 1044 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1045 {
e380f72b 1046 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_in_event" );
034be888
RR
1047 return TRUE;
1048 }
ca298c88 1049
034be888 1050 return FALSE;
362c6693 1051}
c801d85f
KB
1052
1053//-----------------------------------------------------------------------------
2f2aa628
RR
1054// "focus_out_event"
1055//-----------------------------------------------------------------------------
c801d85f 1056
2f2aa628 1057static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
c801d85f 1058{
acfd422a
RR
1059 if (g_isIdle) wxapp_install_idle_handler();
1060
034be888
RR
1061 if (!win->HasVMT()) return FALSE;
1062 if (g_blockEventsOnDrag) return FALSE;
ca298c88 1063
e380f72b
RR
1064 if (win->m_wxwindow)
1065 {
1066 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
1067 GTK_WIDGET_UNSET_FLAGS (win->m_wxwindow, GTK_HAS_FOCUS);
1068 }
47d67540 1069
c801d85f 1070/*
1e133b7d 1071 wxPrintf( _T("OnKillFocus from ") );
e380f72b 1072 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1e133b7d
RR
1073 wxPrintf( win->GetClassInfo()->GetClassName() );
1074 wxPrintf( _T(" ") );
1075 wxPrintf( win->GetLabel() );
1076 wxPrintf( _T(".\n") );
c801d85f 1077*/
47d67540 1078
e380f72b
RR
1079 wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() );
1080 event.SetEventObject( win );
47d67540 1081
e380f72b 1082 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1083 {
e380f72b 1084 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus_out_event" );
034be888
RR
1085 return TRUE;
1086 }
ca298c88 1087
034be888 1088 return FALSE;
362c6693 1089}
c801d85f 1090
b4071e91
RR
1091//-----------------------------------------------------------------------------
1092// "enter_notify_event"
1093//-----------------------------------------------------------------------------
1094
1095static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
1096{
acfd422a
RR
1097 if (g_isIdle) wxapp_install_idle_handler();
1098
034be888
RR
1099 if (!win->HasVMT()) return FALSE;
1100 if (g_blockEventsOnDrag) return FALSE;
ca298c88 1101
58d1c1ae 1102 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
47d67540 1103
1b3667ab
RR
1104 if ((widget->window) && (win->m_cursor.Ok()))
1105 gdk_window_set_cursor( widget->window, win->m_cursor.GetCursor() );
b292e2f5 1106
d8c83875 1107/*
e380f72b
RR
1108 printf( "OnEnter from " );
1109 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1110 printf( win->GetClassInfo()->GetClassName() );
1111 printf( ".\n" );
d8c83875 1112*/
47d67540 1113
e380f72b
RR
1114 wxMouseEvent event( wxEVT_ENTER_WINDOW );
1115 event.SetEventObject( win );
ff8bfdbb 1116
4a33eba6
RR
1117 int x = 0;
1118 int y = 0;
1119 GdkModifierType state = (GdkModifierType)0;
ff8bfdbb 1120
4a33eba6 1121 gdk_window_get_pointer( widget->window, &x, &y, &state );
ff8bfdbb 1122
4a33eba6
RR
1123 event.m_shiftDown = (state & GDK_SHIFT_MASK);
1124 event.m_controlDown = (state & GDK_CONTROL_MASK);
1125 event.m_altDown = (state & GDK_MOD1_MASK);
1126 event.m_metaDown = (state & GDK_MOD2_MASK);
1127 event.m_leftDown = (state & GDK_BUTTON1_MASK);
1128 event.m_middleDown = (state & GDK_BUTTON2_MASK);
1129 event.m_rightDown = (state & GDK_BUTTON3_MASK);
1130
1131 event.m_x = (long)x;
1132 event.m_y = (long)y;
ff8bfdbb 1133
e380f72b 1134 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1135 {
e380f72b 1136 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "enter_notify_event" );
034be888
RR
1137 return TRUE;
1138 }
ca298c88 1139
034be888 1140 return FALSE;
b4071e91 1141}
47d67540 1142
b4071e91
RR
1143//-----------------------------------------------------------------------------
1144// "leave_notify_event"
1145//-----------------------------------------------------------------------------
1146
1147static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
1148{
acfd422a
RR
1149 if (g_isIdle) wxapp_install_idle_handler();
1150
034be888
RR
1151 if (!win->HasVMT()) return FALSE;
1152 if (g_blockEventsOnDrag) return FALSE;
47d67540 1153
58d1c1ae 1154 if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
ca298c88 1155
1b3667ab 1156 if (widget->window)
b292e2f5
RR
1157 gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() );
1158
d8c83875 1159/*
58d1c1ae 1160 wxPrintf( _T("OnLeave from ") );
e380f72b 1161 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
58d1c1ae
RR
1162 wxPrintf( win->GetClassInfo()->GetClassName() );
1163 wxPrintf( _T(".\n") );
d8c83875 1164*/
47d67540 1165
e380f72b
RR
1166 wxMouseEvent event( wxEVT_LEAVE_WINDOW );
1167 event.SetEventObject( win );
47d67540 1168
4a33eba6
RR
1169 int x = 0;
1170 int y = 0;
1171 GdkModifierType state = (GdkModifierType)0;
ff8bfdbb 1172
4a33eba6 1173 gdk_window_get_pointer( widget->window, &x, &y, &state );
ff8bfdbb 1174
4a33eba6
RR
1175 event.m_shiftDown = (state & GDK_SHIFT_MASK);
1176 event.m_controlDown = (state & GDK_CONTROL_MASK);
1177 event.m_altDown = (state & GDK_MOD1_MASK);
1178 event.m_metaDown = (state & GDK_MOD2_MASK);
1179 event.m_leftDown = (state & GDK_BUTTON1_MASK);
1180 event.m_middleDown = (state & GDK_BUTTON2_MASK);
1181 event.m_rightDown = (state & GDK_BUTTON3_MASK);
1182
1183 event.m_x = (long)x;
1184 event.m_y = (long)y;
ff8bfdbb 1185
e380f72b 1186 if (win->GetEventHandler()->ProcessEvent( event ))
034be888 1187 {
e380f72b 1188 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "leave_notify_event" );
034be888
RR
1189 return TRUE;
1190 }
ca298c88 1191
034be888 1192 return FALSE;
b4071e91 1193}
47d67540 1194
c801d85f 1195//-----------------------------------------------------------------------------
2f2aa628
RR
1196// "value_changed" from m_vAdjust
1197//-----------------------------------------------------------------------------
c801d85f 1198
2f2aa628 1199static void gtk_window_vscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
c801d85f 1200{
acfd422a
RR
1201 if (g_isIdle) wxapp_install_idle_handler();
1202
e380f72b 1203 if (g_blockEventsOnDrag) return;
c801d85f
KB
1204
1205/*
e380f72b
RR
1206 printf( "OnVScroll from " );
1207 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1208 printf( win->GetClassInfo()->GetClassName() );
1209 printf( ".\n" );
c801d85f 1210*/
47d67540 1211
e380f72b 1212 if (!win->HasVMT()) return;
47d67540 1213
e380f72b
RR
1214 float diff = win->m_vAdjust->value - win->m_oldVerticalPos;
1215 if (fabs(diff) < 0.2) return;
828f655f 1216 win->m_oldVerticalPos = win->m_vAdjust->value;
47d67540 1217
e380f72b 1218 wxEventType command = wxEVT_NULL;
47d67540 1219
e380f72b
RR
1220 float line_step = win->m_vAdjust->step_increment;
1221 float page_step = win->m_vAdjust->page_increment;
47d67540 1222
76ed8f8d
RR
1223 if (win->m_isScrolling)
1224 {
1225 command = wxEVT_SCROLL_THUMBTRACK;
1226 }
1227 else
1228 {
1229 if (fabs(win->m_vAdjust->value-win->m_vAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM;
1230 else if (fabs(win->m_vAdjust->value-win->m_vAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP;
1231 else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
1232 else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
1233 else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
1234 else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
1235 else command = wxEVT_SCROLL_THUMBTRACK;
1236 }
47d67540 1237
e380f72b 1238 int value = (int)(win->m_vAdjust->value+0.5);
c801d85f 1239
e380f72b
RR
1240 wxScrollEvent event( command, win->GetId(), value, wxVERTICAL );
1241 event.SetEventObject( win );
1242 win->GetEventHandler()->ProcessEvent( event );
362c6693 1243}
c801d85f
KB
1244
1245//-----------------------------------------------------------------------------
2f2aa628
RR
1246// "value_changed" from m_hAdjust
1247//-----------------------------------------------------------------------------
c801d85f 1248
2f2aa628 1249static void gtk_window_hscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
47d67540 1250{
acfd422a
RR
1251 if (g_isIdle) wxapp_install_idle_handler();
1252
e380f72b 1253 if (g_blockEventsOnDrag) return;
47d67540 1254
c801d85f 1255/*
e380f72b
RR
1256 printf( "OnHScroll from " );
1257 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1258 printf( win->GetClassInfo()->GetClassName() );
1259 printf( ".\n" );
c801d85f 1260*/
47d67540 1261
e380f72b 1262 if (!win->HasVMT()) return;
47d67540 1263
e380f72b
RR
1264 float diff = win->m_hAdjust->value - win->m_oldHorizontalPos;
1265 if (fabs(diff) < 0.2) return;
828f655f 1266 win->m_oldHorizontalPos = win->m_hAdjust->value;
47d67540 1267
e380f72b 1268 wxEventType command = wxEVT_NULL;
47d67540 1269
e380f72b
RR
1270 float line_step = win->m_hAdjust->step_increment;
1271 float page_step = win->m_hAdjust->page_increment;
8bbe427f 1272
76ed8f8d
RR
1273 if (win->m_isScrolling)
1274 {
1275 command = wxEVT_SCROLL_THUMBTRACK;
1276 }
1277 else
1278 {
1279 if (fabs(win->m_hAdjust->value-win->m_hAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM;
1280 else if (fabs(win->m_hAdjust->value-win->m_hAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP;
1281 else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
1282 else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
1283 else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
1284 else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
1285 else command = wxEVT_SCROLL_THUMBTRACK;
1286 }
c801d85f 1287
e380f72b 1288 int value = (int)(win->m_hAdjust->value+0.5);
47d67540 1289
e380f72b
RR
1290 wxScrollEvent event( command, win->GetId(), value, wxHORIZONTAL );
1291 event.SetEventObject( win );
1292 win->GetEventHandler()->ProcessEvent( event );
362c6693 1293}
c801d85f
KB
1294
1295//-----------------------------------------------------------------------------
2f2aa628
RR
1296// "changed" from m_vAdjust
1297//-----------------------------------------------------------------------------
c801d85f 1298
2f2aa628 1299static void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
c801d85f 1300{
acfd422a
RR
1301 if (g_isIdle) wxapp_install_idle_handler();
1302
e380f72b 1303 if (g_blockEventsOnDrag) return;
c801d85f
KB
1304
1305/*
e380f72b
RR
1306 printf( "OnVScroll change from " );
1307 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1308 printf( win->GetClassInfo()->GetClassName() );
1309 printf( ".\n" );
c801d85f 1310*/
47d67540 1311
e380f72b 1312 if (!win->HasVMT()) return;
47d67540 1313
e380f72b
RR
1314 wxEventType command = wxEVT_SCROLL_THUMBTRACK;
1315 int value = (int)(win->m_vAdjust->value+0.5);
c801d85f 1316
e380f72b
RR
1317 wxScrollEvent event( command, win->GetId(), value, wxVERTICAL );
1318 event.SetEventObject( win );
1319 win->GetEventHandler()->ProcessEvent( event );
362c6693 1320}
c801d85f
KB
1321
1322//-----------------------------------------------------------------------------
2f2aa628
RR
1323// "changed" from m_hAdjust
1324//-----------------------------------------------------------------------------
c801d85f 1325
2f2aa628 1326static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
47d67540 1327{
acfd422a
RR
1328 if (g_isIdle) wxapp_install_idle_handler();
1329
e380f72b 1330 if (g_blockEventsOnDrag) return;
47d67540 1331
c801d85f 1332/*
e380f72b
RR
1333 printf( "OnHScroll change from " );
1334 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1335 printf( win->GetClassInfo()->GetClassName() );
1336 printf( ".\n" );
c801d85f 1337*/
47d67540 1338
e380f72b 1339 if (!win->HasVMT()) return;
47d67540 1340
e380f72b
RR
1341 wxEventType command = wxEVT_SCROLL_THUMBTRACK;
1342 int value = (int)(win->m_hAdjust->value+0.5);
47d67540 1343
e380f72b
RR
1344 wxScrollEvent event( command, win->GetId(), value, wxHORIZONTAL );
1345 event.SetEventObject( win );
1346 win->GetEventHandler()->ProcessEvent( event );
362c6693 1347}
c801d85f 1348
cb43b372
RR
1349//-----------------------------------------------------------------------------
1350// "button_press_event" from scrollbar
1351//-----------------------------------------------------------------------------
1352
8bbe427f
VZ
1353static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
1354 GdkEventButton *WXUNUSED(gdk_event),
ff8bfdbb 1355 wxWindow *win )
cb43b372 1356{
acfd422a
RR
1357 if (g_isIdle) wxapp_install_idle_handler();
1358
1ecc4d80
RR
1359// don't test here as we can release the mouse while being over
1360// a different window then the slider
1361//
76ed8f8d 1362// if (gdk_event->window != widget->slider) return FALSE;
8bbe427f 1363
e380f72b 1364 win->m_isScrolling = TRUE;
76ed8f8d 1365 g_blockEventsOnScroll = TRUE;
47d67540 1366
e380f72b 1367 return FALSE;
cb43b372
RR
1368}
1369
1370//-----------------------------------------------------------------------------
1371// "button_release_event" from scrollbar
1372//-----------------------------------------------------------------------------
1373
8bbe427f
VZ
1374static gint gtk_scrollbar_button_release_callback( GtkRange *widget,
1375 GdkEventButton *WXUNUSED(gdk_event),
ff8bfdbb 1376 wxWindow *win )
cb43b372 1377{
acfd422a 1378 if (g_isIdle) wxapp_install_idle_handler();
76ed8f8d 1379
1ecc4d80 1380// don't test here as we can release the mouse while being over
76ed8f8d
RR
1381// a different window then the slider
1382//
1383// if (gdk_event->window != widget->slider) return FALSE;
cb43b372 1384
e380f72b 1385 GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(win->m_widget);
47d67540 1386
e380f72b
RR
1387 if (widget == GTK_RANGE(s_window->vscrollbar))
1388 gtk_signal_emit_by_name( GTK_OBJECT(win->m_hAdjust), "value_changed" );
1389 else
1390 gtk_signal_emit_by_name( GTK_OBJECT(win->m_vAdjust), "value_changed" );
47d67540 1391
e380f72b 1392 win->m_isScrolling = FALSE;
76ed8f8d 1393 g_blockEventsOnScroll = FALSE;
47d67540 1394
e380f72b 1395 return FALSE;
cb43b372
RR
1396}
1397
2b07d713
RR
1398//-----------------------------------------------------------------------------
1399// "realize" from m_widget
1400//-----------------------------------------------------------------------------
1401
1402/* we cannot set colours, fonts and cursors before the widget has
1403 been realized, so we do this directly after realization */
1404
ca298c88 1405static gint
2b07d713
RR
1406gtk_window_realized_callback( GtkWidget *widget, wxWindow *win )
1407{
acfd422a
RR
1408 if (g_isIdle) wxapp_install_idle_handler();
1409
2b07d713
RR
1410 if (win->m_font != *wxSWISS_FONT)
1411 {
1412 wxFont font( win->m_font );
1413 win->m_font = wxNullFont;
1414 win->SetFont( font );
1415 }
ca298c88 1416
2b07d713
RR
1417 if (win->m_backgroundColour != wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE ))
1418 {
1419 wxColour bg( win->m_backgroundColour );
1e133b7d 1420 win->m_backgroundColour = wxNullColour;
2b07d713
RR
1421 win->SetBackgroundColour( bg );
1422 }
ca298c88 1423
2b07d713
RR
1424 if (win->m_foregroundColour != *wxBLACK)
1425 {
1426 wxColour fg( win->m_foregroundColour );
1e133b7d 1427 win->m_foregroundColour = wxNullColour;
2b07d713
RR
1428 win->SetForegroundColour( fg );
1429 }
ca298c88 1430
1b3667ab
RR
1431 wxCursor cursor( win->m_cursor );
1432 win->m_cursor = wxNullCursor;
1433 win->SetCursor( cursor );
ca298c88 1434
2b07d713
RR
1435 return FALSE;
1436}
ca298c88 1437
6ca41e57
RR
1438//-----------------------------------------------------------------------------
1439// InsertChild for wxWindow.
1440//-----------------------------------------------------------------------------
1441
b1170810
RR
1442/* Callback for wxWindow. This very strange beast has to be used because
1443 * C++ has no virtual methods in a constructor. We have to emulate a
1444 * virtual function here as wxNotebook requires a different way to insert
1445 * a child in it. I had opted for creating a wxNotebookPage window class
1446 * which would have made this superfluous (such in the MDI window system),
1447 * but no-one was listening to me... */
6ca41e57
RR
1448
1449static void wxInsertChildInWindow( wxWindow* parent, wxWindow* child )
1450{
8bbe427f
VZ
1451 gtk_myfixed_put( GTK_MYFIXED(parent->m_wxwindow),
1452 GTK_WIDGET(child->m_widget),
e208b369 1453 child->m_x,
fdd3ed7a
RR
1454 child->m_y,
1455 child->m_width,
1456 child->m_height );
e208b369 1457
3e61c765
RR
1458 if (parent->m_windowStyle & wxTAB_TRAVERSAL)
1459 {
1460 /* we now allow a window to get the focus as long as it
ff8bfdbb
VZ
1461 doesn't have any children. */
1462 GTK_WIDGET_UNSET_FLAGS( parent->m_wxwindow, GTK_CAN_FOCUS );
3e61c765 1463 }
6ca41e57
RR
1464}
1465
bbe0af5b
RR
1466//-----------------------------------------------------------------------------
1467// global functions
1468//-----------------------------------------------------------------------------
1469
1470wxWindow* wxGetActiveWindow()
1471{
1472 return g_focusWindow;
1473}
1474
c801d85f 1475//-----------------------------------------------------------------------------
2f2aa628 1476// wxWindow
c801d85f
KB
1477//-----------------------------------------------------------------------------
1478
1479IMPLEMENT_DYNAMIC_CLASS(wxWindow,wxEvtHandler)
1480
1481BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
e380f72b
RR
1482 EVT_SIZE(wxWindow::OnSize)
1483 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
1484 EVT_INIT_DIALOG(wxWindow::OnInitDialog)
b666df2c 1485 EVT_KEY_DOWN(wxWindow::OnKeyDown)
c801d85f
KB
1486END_EVENT_TABLE()
1487
68995f26 1488void wxWindow::Init()
c801d85f 1489{
68995f26
VZ
1490 m_isWindow = TRUE;
1491
e380f72b
RR
1492 m_widget = (GtkWidget *) NULL;
1493 m_wxwindow = (GtkWidget *) NULL;
1494 m_parent = (wxWindow *) NULL;
1495 m_children.DeleteContents( FALSE );
8bbe427f 1496
e380f72b
RR
1497 m_x = 0;
1498 m_y = 0;
1499 m_width = 0;
1500 m_height = 0;
1501 m_minWidth = -1;
1502 m_minHeight = -1;
1503 m_maxWidth = -1;
1504 m_maxHeight = -1;
8bbe427f 1505
e380f72b 1506 m_retCode = 0;
8bbe427f 1507
e380f72b
RR
1508 m_eventHandler = this;
1509 m_windowValidator = (wxValidator *) NULL;
8bbe427f 1510
e380f72b 1511 m_windowId = -1;
8bbe427f 1512
1b3667ab 1513 m_cursor = *wxSTANDARD_CURSOR;
e380f72b
RR
1514 m_font = *wxSWISS_FONT;
1515 m_windowStyle = 0;
1516 m_windowName = "noname";
8bbe427f 1517
e380f72b
RR
1518 m_constraints = (wxLayoutConstraints *) NULL;
1519 m_constraintsInvolvedIn = (wxList *) NULL;
1520 m_windowSizer = (wxSizer *) NULL;
1521 m_sizerParent = (wxWindow *) NULL;
1522 m_autoLayout = FALSE;
8bbe427f 1523
e380f72b
RR
1524 m_sizeSet = FALSE;
1525 m_hasVMT = FALSE;
1526 m_needParent = TRUE;
8bbe427f 1527
e380f72b
RR
1528 m_hasScrolling = FALSE;
1529 m_isScrolling = FALSE;
1530 m_hAdjust = (GtkAdjustment*) NULL;
1531 m_vAdjust = (GtkAdjustment*) NULL;
1532 m_oldHorizontalPos = 0.0;
1533 m_oldVerticalPos = 0.0;
8bbe427f 1534
e380f72b
RR
1535 m_isShown = FALSE;
1536 m_isEnabled = TRUE;
8bbe427f 1537
06cfab17 1538#if wxUSE_DRAG_AND_DROP
e380f72b 1539 m_dropTarget = (wxDropTarget*) NULL;
ac57418f 1540#endif
e380f72b
RR
1541 m_resizing = FALSE;
1542 m_scrollGC = (GdkGC*) NULL;
1543 m_widgetStyle = (GtkStyle*) NULL;
8bbe427f 1544
e380f72b 1545 m_insertCallback = wxInsertChildInWindow;
8bbe427f 1546
e380f72b
RR
1547 m_clientObject = (wxClientData*) NULL;
1548 m_clientData = NULL;
ff8bfdbb 1549
1ecc4d80 1550 m_isStaticBox = FALSE;
b292e2f5 1551 m_acceptsFocus = FALSE;
ff8bfdbb
VZ
1552
1553#if wxUSE_TOOLTIPS
b1170810 1554 m_toolTip = (wxToolTip*) NULL;
ff8bfdbb 1555#endif // wxUSE_TOOLTIPS
362c6693 1556}
c801d85f 1557
68995f26
VZ
1558wxWindow::wxWindow()
1559{
1560 Init();
1561}
1562
6ca41e57 1563wxWindow::wxWindow( wxWindow *parent, wxWindowID id,
e380f72b
RR
1564 const wxPoint &pos, const wxSize &size,
1565 long style, const wxString &name )
6ca41e57 1566{
68995f26
VZ
1567 Init();
1568
e380f72b 1569 Create( parent, id, pos, size, style, name );
6ca41e57 1570}
8bbe427f 1571
debe6624 1572bool wxWindow::Create( wxWindow *parent, wxWindowID id,
e380f72b
RR
1573 const wxPoint &pos, const wxSize &size,
1574 long style, const wxString &name )
c801d85f 1575{
05939a81 1576 wxASSERT_MSG( m_isWindow, _T("Init() must have been called before!") );
47d67540 1577
e380f72b 1578 PreCreation( parent, id, pos, size, style, name );
47d67540 1579
e380f72b 1580 m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
38c7b3d3 1581 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
ff8bfdbb 1582
2e563988
RR
1583#ifdef __WXDEBUG__
1584 debug_focus_in( m_widget, _T("wxWindow::m_widget"), name );
1585#endif
1586
e380f72b 1587 GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget);
47d67540 1588
2e563988
RR
1589#ifdef __WXDEBUG__
1590 debug_focus_in( s_window->hscrollbar, _T("wxWindow::hsrcollbar"), name );
1591 debug_focus_in( s_window->vscrollbar, _T("wxWindow::vsrcollbar"), name );
1592#endif
1593
e380f72b
RR
1594 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
1595 scroll_class->scrollbar_spacing = 0;
47d67540 1596
e380f72b 1597 gtk_scrolled_window_set_policy( s_window, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
47d67540 1598
e380f72b
RR
1599 m_oldHorizontalPos = 0.0;
1600 m_oldVerticalPos = 0.0;
47d67540 1601
e380f72b
RR
1602 m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) );
1603 m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) );
47d67540 1604
38c7b3d3
RR
1605 m_wxwindow = gtk_myfixed_new();
1606
2e563988
RR
1607#ifdef __WXDEBUG__
1608 debug_focus_in( m_wxwindow, _T("wxWindow::m_wxwindow"), name );
1609#endif
1610
034be888 1611 gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
58dea4b0 1612
034be888
RR
1613#if (GTK_MINOR_VERSION > 0)
1614 GtkMyFixed *myfixed = GTK_MYFIXED(m_wxwindow);
b292e2f5 1615
034be888
RR
1616 if (m_windowStyle & wxRAISED_BORDER)
1617 {
1618 gtk_myfixed_set_shadow_type( myfixed, GTK_SHADOW_OUT );
1619 }
1620 else if (m_windowStyle & wxSUNKEN_BORDER)
1621 {
1622 gtk_myfixed_set_shadow_type( myfixed, GTK_SHADOW_IN );
1623 }
1624 else
1625 {
1626 gtk_myfixed_set_shadow_type( myfixed, GTK_SHADOW_NONE );
1627 }
38c7b3d3 1628#else
e380f72b 1629 GtkViewport *viewport = GTK_VIEWPORT(s_window->viewport);
b292e2f5 1630
e380f72b
RR
1631 if (m_windowStyle & wxRAISED_BORDER)
1632 {
1633 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_OUT );
1634 }
1635 else if (m_windowStyle & wxSUNKEN_BORDER)
1636 {
1637 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_IN );
1638 }
1639 else
1640 {
1641 gtk_viewport_set_shadow_type( viewport, GTK_SHADOW_NONE );
1642 }
034be888 1643#endif
47d67540 1644
13393ab6
RR
1645 /* we always allow a window to get the focus as long as it
1646 doesn't have any children. */
3e61c765 1647 if (m_windowStyle & wxTAB_TRAVERSAL)
b292e2f5 1648 {
ff8bfdbb 1649 GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
b292e2f5
RR
1650 m_acceptsFocus = FALSE;
1651 }
e380f72b 1652 else
b292e2f5 1653 {
e380f72b 1654 GTK_WIDGET_SET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
b292e2f5
RR
1655 m_acceptsFocus = TRUE;
1656 }
ca298c88 1657
13393ab6 1658 /* grab the actual focus */
2e563988 1659// gtk_widget_grab_focus( m_wxwindow );
e380f72b 1660
f9a273cd
KB
1661 gtk_widget_show( m_wxwindow );
1662
ca298c88 1663
034be888 1664#if (GTK_MINOR_VERSION == 0)
e380f72b
RR
1665 // shut the viewport up
1666 gtk_viewport_set_hadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1667 gtk_viewport_set_vadjustment( viewport, (GtkAdjustment*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
034be888 1668#endif
e380f72b
RR
1669
1670 // I _really_ don't want scrollbars in the beginning
1671 m_vAdjust->lower = 0.0;
1672 m_vAdjust->upper = 1.0;
1673 m_vAdjust->value = 0.0;
1674 m_vAdjust->step_increment = 1.0;
1675 m_vAdjust->page_increment = 1.0;
1676 m_vAdjust->page_size = 5.0;
1677 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
1678 m_hAdjust->lower = 0.0;
1679 m_hAdjust->upper = 1.0;
1680 m_hAdjust->value = 0.0;
1681 m_hAdjust->step_increment = 1.0;
1682 m_hAdjust->page_increment = 1.0;
1683 m_hAdjust->page_size = 5.0;
1684 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
1685
76ed8f8d
RR
1686 // these handlers block mouse events to any window during scrolling
1687 // such as motion events and prevent GTK and wxWindows from fighting
1688 // over where the slider should be
8bbe427f 1689
76ed8f8d
RR
1690 gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_press_event",
1691 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1692
1693 gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event",
1694 (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
1695
1696 gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event",
1697 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
1698
1699 gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event",
1700 (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
8bbe427f 1701
034be888 1702 // these handlers get notified when screen updates are required either when
76ed8f8d
RR
1703 // scrolling or when the window size (and therefore scrollbar configuration)
1704 // has changed
1705
1706 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
1707 (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
1708 gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
1709 (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
1710
1711 gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
1712 (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
1713 gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
1714 (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
1715
e380f72b 1716 if (m_parent) m_parent->AddChild( this );
47d67540 1717
e380f72b 1718 (m_parent->m_insertCallback)( m_parent, this );
8bbe427f 1719
e380f72b 1720 PostCreation();
8bbe427f 1721
e380f72b 1722 Show( TRUE );
c801d85f 1723
e380f72b 1724 return TRUE;
362c6693 1725}
c801d85f 1726
68dda785 1727wxWindow::~wxWindow()
c801d85f 1728{
43a18898 1729 m_hasVMT = FALSE;
47d67540 1730
06cfab17 1731#if wxUSE_DRAG_AND_DROP
e27ce4e9
RR
1732 if (m_dropTarget)
1733 {
1734 delete m_dropTarget;
1735 m_dropTarget = (wxDropTarget*) NULL;
1736 }
ac57418f 1737#endif
47d67540 1738
ff8bfdbb 1739#if wxUSE_TOOLTIPS
e27ce4e9
RR
1740 if (m_toolTip)
1741 {
1742 delete m_toolTip;
1743 m_toolTip = (wxToolTip*) NULL;
1744 }
ff8bfdbb 1745#endif // wxUSE_TOOLTIPS
b1170810 1746
43a18898 1747 if (m_widget) Show( FALSE );
c801d85f 1748
43a18898 1749 DestroyChildren();
47d67540 1750
e27ce4e9 1751 if (m_parent) m_parent->RemoveChild( this );
ca298c88 1752
43a18898 1753 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
8bbe427f 1754
43a18898 1755 if (m_scrollGC) gdk_gc_unref( m_scrollGC );
8bbe427f 1756
43a18898 1757 if (m_wxwindow) gtk_widget_destroy( m_wxwindow );
47d67540 1758
43a18898 1759 if (m_widget) gtk_widget_destroy( m_widget );
8bbe427f 1760
43a18898
RR
1761 DeleteRelatedConstraints();
1762 if (m_constraints)
1763 {
e27ce4e9
RR
1764 /* This removes any dangling pointers to this window
1765 * in other windows' constraintsInvolvedIn lists. */
43a18898
RR
1766 UnsetConstraints(m_constraints);
1767 delete m_constraints;
1768 m_constraints = (wxLayoutConstraints *) NULL;
1769 }
ca298c88 1770
43a18898
RR
1771 if (m_windowSizer)
1772 {
1773 delete m_windowSizer;
1774 m_windowSizer = (wxSizer *) NULL;
1775 }
e27ce4e9 1776 /* If this is a child of a sizer, remove self from parent */
43a18898 1777 if (m_sizerParent) m_sizerParent->RemoveChild((wxWindow *)this);
c801d85f 1778
e27ce4e9
RR
1779 /* Just in case the window has been Closed, but
1780 * we're then deleting immediately: don't leave
1781 * dangling pointers. */
43a18898 1782 wxPendingDelete.DeleteObject(this);
c801d85f 1783
e27ce4e9
RR
1784 /* Just in case we've loaded a top-level window via
1785 * wxWindow::LoadNativeDialog but we weren't a dialog
1786 * class */
43a18898 1787 wxTopLevelWindows.DeleteObject(this);
47d67540 1788
43a18898 1789 if (m_windowValidator) delete m_windowValidator;
8bbe427f 1790
43a18898 1791 if (m_clientObject) delete m_clientObject;
362c6693 1792}
c801d85f 1793
debe6624
JS
1794void wxWindow::PreCreation( wxWindow *parent, wxWindowID id,
1795 const wxPoint &pos, const wxSize &size,
1796 long style, const wxString &name )
c801d85f 1797{
05939a81 1798 wxASSERT_MSG( (!m_needParent) || (parent), _T("Need complete parent.") );
8bbe427f 1799
43a18898
RR
1800 m_widget = (GtkWidget*) NULL;
1801 m_wxwindow = (GtkWidget*) NULL;
1802 m_hasVMT = FALSE;
1803 m_parent = parent;
1804 m_children.DeleteContents( FALSE );
8bbe427f 1805
43a18898
RR
1806 m_width = size.x;
1807 if (m_width == -1) m_width = 20;
1808 m_height = size.y;
1809 if (m_height == -1) m_height = 20;
8bbe427f 1810
43a18898
RR
1811 m_x = (int)pos.x;
1812 m_y = (int)pos.y;
8bbe427f 1813
e27ce4e9 1814 if (!m_needParent) /* some reasonable defaults */
6ca41e57 1815 {
43a18898
RR
1816 if (m_x == -1)
1817 {
1818 m_x = (gdk_screen_width () - m_width) / 2;
1819 if (m_x < 10) m_x = 10;
1820 }
1821 if (m_y == -1)
1822 {
1823 m_y = (gdk_screen_height () - m_height) / 2;
1824 if (m_y < 10) m_y = 10;
1825 }
6ca41e57 1826 }
8bbe427f 1827
43a18898
RR
1828 m_minWidth = -1;
1829 m_minHeight = -1;
1830 m_maxWidth = -1;
1831 m_maxHeight = -1;
8bbe427f 1832
43a18898 1833 m_retCode = 0;
8bbe427f 1834
43a18898 1835 m_eventHandler = this;
8bbe427f 1836
b749747d 1837 m_windowId = id == -1 ? wxNewId() : id;
8bbe427f 1838
43a18898 1839 m_sizeSet = FALSE;
8bbe427f 1840
1b3667ab 1841 m_cursor = *wxSTANDARD_CURSOR;
43a18898 1842 m_font = *wxSWISS_FONT;
1ecc4d80
RR
1843 m_backgroundColour = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
1844 m_foregroundColour = *wxBLACK;
43a18898
RR
1845 m_windowStyle = style;
1846 m_windowName = name;
8bbe427f 1847
43a18898
RR
1848 m_constraints = (wxLayoutConstraints *) NULL;
1849 m_constraintsInvolvedIn = (wxList *) NULL;
1850 m_windowSizer = (wxSizer *) NULL;
1851 m_sizerParent = (wxWindow *) NULL;
1852 m_autoLayout = FALSE;
8bbe427f 1853
43a18898
RR
1854 m_hasScrolling = FALSE;
1855 m_isScrolling = FALSE;
1856 m_hAdjust = (GtkAdjustment *) NULL;
1857 m_vAdjust = (GtkAdjustment *) NULL;
1858 m_oldHorizontalPos = 0.0;
1859 m_oldVerticalPos = 0.0;
8bbe427f 1860
43a18898
RR
1861 m_isShown = FALSE;
1862 m_isEnabled = TRUE;
8bbe427f 1863
06cfab17 1864#if wxUSE_DRAG_AND_DROP
43a18898 1865 m_dropTarget = (wxDropTarget *) NULL;
ac57418f 1866#endif
43a18898
RR
1867 m_resizing = FALSE;
1868 m_windowValidator = (wxValidator *) NULL;
1869 m_scrollGC = (GdkGC*) NULL;
1870 m_widgetStyle = (GtkStyle*) NULL;
8bbe427f 1871
43a18898
RR
1872 m_clientObject = (wxClientData*)NULL;
1873 m_clientData = NULL;
ff8bfdbb 1874
1ecc4d80 1875 m_isStaticBox = FALSE;
ff8bfdbb
VZ
1876
1877#if wxUSE_TOOLTIPS
b1170810 1878 m_toolTip = (wxToolTip*) NULL;
ff8bfdbb 1879#endif // wxUSE_TOOLTIPS
c801d85f
KB
1880}
1881
68dda785 1882void wxWindow::PostCreation()
c801d85f 1883{
05939a81 1884 wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
ca298c88 1885
43a18898
RR
1886 if (m_wxwindow)
1887 {
034be888 1888 /* these get reported to wxWindows -> wxPaintEvent */
20239453
RR
1889 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event",
1890 GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this );
47d67540 1891
20239453
RR
1892 gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw",
1893 GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
ca298c88 1894
ef47f9b3 1895#if (GTK_MINOR_VERSION > 0)
034be888
RR
1896 /* these are called when the "sunken" or "raised" borders are drawn */
1897 gtk_signal_connect( GTK_OBJECT(m_widget), "expose_event",
1898 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this );
1899
1900 gtk_signal_connect( GTK_OBJECT(m_widget), "draw",
1901 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback), (gpointer)this );
ef47f9b3 1902#endif
43a18898 1903 }
47d67540 1904
1e133b7d
RR
1905 GtkWidget *connect_widget = GetConnectWidget();
1906
1907 ConnectWidget( connect_widget );
47d67540 1908
1e133b7d
RR
1909 /* we cannot set colours, fonts and cursors before the widget has
1910 been realized, so we do this directly after realization */
1911 gtk_signal_connect( GTK_OBJECT(connect_widget), "realize",
2b07d713 1912 GTK_SIGNAL_FUNC(gtk_window_realized_callback), (gpointer) this );
ca298c88 1913
43a18898 1914 m_hasVMT = TRUE;
b4071e91
RR
1915}
1916
1917void wxWindow::ConnectWidget( GtkWidget *widget )
1918{
43a18898
RR
1919 gtk_signal_connect( GTK_OBJECT(widget), "key_press_event",
1920 GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
c801d85f 1921
b666df2c
RR
1922 gtk_signal_connect( GTK_OBJECT(widget), "key_release_event",
1923 GTK_SIGNAL_FUNC(gtk_window_key_release_callback), (gpointer)this );
1924
43a18898
RR
1925 gtk_signal_connect( GTK_OBJECT(widget), "button_press_event",
1926 GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
47d67540 1927
43a18898
RR
1928 gtk_signal_connect( GTK_OBJECT(widget), "button_release_event",
1929 GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
47d67540 1930
43a18898
RR
1931 gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event",
1932 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
47d67540 1933
43a18898
RR
1934 gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event",
1935 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
c801d85f 1936
43a18898
RR
1937 gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event",
1938 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
c801d85f 1939
43a18898
RR
1940 gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event",
1941 GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
47d67540 1942
43a18898
RR
1943 gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event",
1944 GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
362c6693 1945}
c801d85f 1946
68dda785 1947bool wxWindow::HasVMT()
c801d85f 1948{
43a18898 1949 return m_hasVMT;
362c6693 1950}
c801d85f 1951
debe6624 1952bool wxWindow::Close( bool force )
c801d85f 1953{
05939a81 1954 wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
47d67540 1955
43a18898
RR
1956 wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
1957 event.SetEventObject(this);
2b854a32 1958 event.SetCanVeto(!force);
c801d85f 1959
e27ce4e9
RR
1960 /* return FALSE if window wasn't closed because the application vetoed the
1961 * close event */
fe4e9e6c 1962 return GetEventHandler()->ProcessEvent(event) && !event.GetVeto();
362c6693 1963}
c801d85f 1964
68dda785 1965bool wxWindow::Destroy()
c801d85f 1966{
05939a81 1967 wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
47d67540 1968
43a18898
RR
1969 m_hasVMT = FALSE;
1970 delete this;
1971 return TRUE;
362c6693 1972}
c801d85f 1973
68dda785 1974bool wxWindow::DestroyChildren()
c801d85f 1975{
db1b4961
RR
1976 wxNode *node;
1977 while ((node = m_children.First()) != (wxNode *)NULL)
c801d85f 1978 {
db1b4961
RR
1979 wxWindow *child;
1980 if ((child = (wxWindow *)node->Data()) != (wxWindow *)NULL)
43a18898 1981 {
db1b4961
RR
1982 delete child;
1983 if (m_children.Member(child)) delete node;
43a18898 1984 }
362c6693 1985 }
43a18898 1986 return TRUE;
362c6693 1987}
c801d85f
KB
1988
1989void wxWindow::PrepareDC( wxDC &WXUNUSED(dc) )
1990{
43a18898 1991 // are we to set fonts here ?
362c6693 1992}
c801d85f 1993
bfc6fde4 1994void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
c801d85f 1995{
05939a81
OK
1996 wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
1997 wxASSERT_MSG( (m_parent != NULL), _T("wxWindow::SetSize requires parent.\n") );
8bbe427f 1998
e27ce4e9 1999 if (m_resizing) return; /* I don't like recursions */
fb1585ae 2000 m_resizing = TRUE;
47d67540 2001
e208b369 2002 if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook page */
fb1585ae 2003 {
e27ce4e9 2004 /* don't set the size for children of wxNotebook, just take the values. */
fb1585ae
RR
2005 m_x = x;
2006 m_y = y;
2007 m_width = width;
ba4e3652 2008 m_height = height;
fb1585ae 2009 }
ba4e3652 2010 else
fb1585ae 2011 {
ba4e3652
RR
2012 if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
2013 {
2014 if (x != -1) m_x = x;
2015 if (y != -1) m_y = y;
2016 if (width != -1) m_width = width;
2017 if (height != -1) m_height = height;
2018 }
2019 else
2020 {
2021 m_x = x;
2022 m_y = y;
2023 m_width = width;
2024 m_height = height;
2025 }
47d67540 2026
ba4e3652
RR
2027 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
2028 {
2029 if (width == -1) m_width = 80;
2030 }
2031
2032 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
2033 {
2034 if (height == -1) m_height = 26;
2035 }
8bbe427f 2036
ba4e3652
RR
2037 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
2038 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
d3b4d113
RR
2039 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
2040 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
47d67540 2041
fdd3ed7a
RR
2042 int border = 0;
2043
3502e687
RR
2044 if (GTK_WIDGET_HAS_DEFAULT(m_widget))
2045 {
2046 /* the default button has a border around it */
fdd3ed7a 2047 border = 5;
3502e687 2048 }
3502e687 2049
fdd3ed7a
RR
2050 /* this is the result of hours of debugging: the following code
2051 means that if we have a m_wxwindow and we set the size of
2052 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
2053 automatically propagate its size down to its m_wxwindow,
2054 which is its client area. therefore, we have to tell the
2055 client area directly that it has to resize itself.
2056 this will lead to that m_widget (GtkScrolledWindow) will
2057 calculate how much size it needs for scrollbars etc and
2058 it will then call XXX_size_allocate of its child, which
2059 is m_wxwindow. m_wxwindow in turn will do the same with its
2060 children and so on. problems can arise if this happens
2061 before all the children have been realized as some widgets
2062 stupidy need to be realized during XXX_size_allocate (e.g.
2063 GtkNotebook) and they will segv if called otherwise. this
2064 emergency is tested in gtk_myfixed_size_allocate. Normally
2065 this shouldn't be needed and only gtk_widget_queue_resize()
2066 should be enough to provoke a resize at the next appropriate
2067 moment, but this seems to fail, e.g. when a wxNotebook contains
2068 a wxSplitterWindow: the splitter window's children won't
2069 show up properly resized then. */
2070
2071 gtk_myfixed_set_size( GTK_MYFIXED(m_parent->m_wxwindow),
2072 m_widget,
2073 m_x-border,
2074 m_y-border,
2075 m_width+2*border,
2076 m_height+2*border );
e208b369 2077
ba4e3652 2078 }
8bbe427f 2079
fb1585ae 2080 m_sizeSet = TRUE;
47d67540 2081
fb1585ae
RR
2082 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
2083 event.SetEventObject( this );
ba4e3652 2084 GetEventHandler()->ProcessEvent( event );
47d67540 2085
fb1585ae 2086 m_resizing = FALSE;
362c6693 2087}
c801d85f 2088
9390a202
RR
2089void wxWindow::OnInternalIdle()
2090{
2091 UpdateWindowUI();
2092}
2093
c801d85f
KB
2094void wxWindow::GetSize( int *width, int *height ) const
2095{
05939a81 2096 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2097
fb1585ae
RR
2098 if (width) (*width) = m_width;
2099 if (height) (*height) = m_height;
362c6693 2100}
c801d85f 2101
bfc6fde4 2102void wxWindow::DoSetClientSize( int width, int height )
c801d85f 2103{
05939a81 2104 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2105
1ecc4d80 2106 if (!m_wxwindow)
c801d85f 2107 {
1ecc4d80 2108 SetSize( width, height );
c801d85f
KB
2109 }
2110 else
2111 {
1ecc4d80
RR
2112 int dw = 0;
2113 int dh = 0;
2114
2115 if (!m_hasScrolling)
2116 {
2117 GtkStyleClass *window_class = m_wxwindow->style->klass;
2118
2119 if ((m_windowStyle & wxRAISED_BORDER) ||
2120 (m_windowStyle & wxSUNKEN_BORDER))
2121 {
2122 dw += 2 * window_class->xthickness;
2123 dh += 2 * window_class->ythickness;
2124 }
2125 }
2126 else
2127 {
2128 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
2129 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
47d67540 2130
034be888 2131#if (GTK_MINOR_VERSION == 0)
1ecc4d80 2132 GtkWidget *viewport = scroll_window->viewport;
1ecc4d80
RR
2133 GtkStyleClass *viewport_class = viewport->style->klass;
2134
1ecc4d80
RR
2135 if ((m_windowStyle & wxRAISED_BORDER) ||
2136 (m_windowStyle & wxSUNKEN_BORDER))
2137 {
2138 dw += 2 * viewport_class->xthickness;
2139 dh += 2 * viewport_class->ythickness;
2140 }
034be888
RR
2141#endif
2142
2143/*
2144 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2145 GtkWidget *vscrollbar = scroll_window->vscrollbar;
ca298c88
RD
2146
2147 we use this instead: range.slider_width = 11 + 2*2pts edge
034be888 2148*/
47d67540 2149
1ecc4d80
RR
2150 if (scroll_window->vscrollbar_visible)
2151 {
034be888 2152 dw += 15; /* dw += vscrollbar->allocation.width; */
1ecc4d80
RR
2153 dw += scroll_class->scrollbar_spacing;
2154 }
2155
2156 if (scroll_window->hscrollbar_visible)
2157 {
034be888 2158 dh += 15; /* dh += hscrollbar->allocation.height; */
1ecc4d80
RR
2159 dw += scroll_class->scrollbar_spacing;
2160 }
2161 }
2162
034be888 2163 SetSize( width+dw, height+dh );
1ecc4d80 2164 }
362c6693 2165}
c801d85f
KB
2166
2167void wxWindow::GetClientSize( int *width, int *height ) const
2168{
05939a81 2169 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2170
1ecc4d80
RR
2171 if (!m_wxwindow)
2172 {
2173 if (width) (*width) = m_width;
2174 if (height) (*height) = m_height;
c801d85f
KB
2175 }
2176 else
2177 {
1ecc4d80
RR
2178 int dw = 0;
2179 int dh = 0;
2180
2181 if (!m_hasScrolling)
2182 {
2183 GtkStyleClass *window_class = m_wxwindow->style->klass;
2184
2185 if ((m_windowStyle & wxRAISED_BORDER) ||
2186 (m_windowStyle & wxSUNKEN_BORDER))
2187 {
2188 dw += 2 * window_class->xthickness;
2189 dh += 2 * window_class->ythickness;
2190 }
2191 }
2192 else
2193 {
2194 GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
2195 GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
47d67540 2196
034be888 2197#if (GTK_MINOR_VERSION == 0)
1ecc4d80 2198 GtkWidget *viewport = scroll_window->viewport;
1ecc4d80
RR
2199 GtkStyleClass *viewport_class = viewport->style->klass;
2200
2201 if ((m_windowStyle & wxRAISED_BORDER) ||
2202 (m_windowStyle & wxSUNKEN_BORDER))
2203 {
2204 dw += 2 * viewport_class->xthickness;
2205 dh += 2 * viewport_class->ythickness;
2206 }
034be888
RR
2207#endif
2208/*
2209 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2210 GtkWidget *vscrollbar = scroll_window->vscrollbar;
ca298c88
RD
2211
2212 we use this instead: range.slider_width = 11 + 2*2pts edge
034be888 2213*/
1ecc4d80
RR
2214
2215 if (scroll_window->vscrollbar_visible)
2216 {
034be888 2217 dw += 15; /* dw += vscrollbar->allocation.width; */
1ecc4d80
RR
2218 dw += scroll_class->scrollbar_spacing;
2219 }
2220
2221 if (scroll_window->hscrollbar_visible)
2222 {
034be888 2223 dh += 15; /* dh += hscrollbar->allocation.height; */
1ecc4d80
RR
2224 dh += scroll_class->scrollbar_spacing;
2225 }
2226 }
47d67540 2227
1ecc4d80
RR
2228 if (width) (*width) = m_width - dw;
2229 if (height) (*height) = m_height - dh;
2230 }
362c6693 2231}
c801d85f
KB
2232
2233void wxWindow::GetPosition( int *x, int *y ) const
2234{
05939a81 2235 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2236
43a18898
RR
2237 if (x) (*x) = m_x;
2238 if (y) (*y) = m_y;
362c6693 2239}
c801d85f
KB
2240
2241void wxWindow::ClientToScreen( int *x, int *y )
2242{
05939a81 2243 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2244
2b07d713
RR
2245 if (!m_widget->window) return;
2246
43a18898
RR
2247 GdkWindow *source = (GdkWindow *) NULL;
2248 if (m_wxwindow)
2249 source = m_wxwindow->window;
2250 else
2251 source = m_widget->window;
47d67540 2252
43a18898
RR
2253 int org_x = 0;
2254 int org_y = 0;
2255 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 2256
43a18898 2257 if (!m_wxwindow)
c801d85f 2258 {
43a18898
RR
2259 if (GTK_WIDGET_NO_WINDOW (m_widget))
2260 {
2261 org_x += m_widget->allocation.x;
2262 org_y += m_widget->allocation.y;
2263 }
362c6693 2264 }
47d67540 2265
43a18898
RR
2266 if (x) *x += org_x;
2267 if (y) *y += org_y;
362c6693 2268}
c801d85f
KB
2269
2270void wxWindow::ScreenToClient( int *x, int *y )
2271{
05939a81 2272 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2273
2b07d713
RR
2274 if (!m_widget->window) return;
2275
1ecc4d80
RR
2276 GdkWindow *source = (GdkWindow *) NULL;
2277 if (m_wxwindow)
2278 source = m_wxwindow->window;
2279 else
2280 source = m_widget->window;
47d67540 2281
1ecc4d80
RR
2282 int org_x = 0;
2283 int org_y = 0;
2284 gdk_window_get_origin( source, &org_x, &org_y );
c801d85f 2285
1ecc4d80 2286 if (!m_wxwindow)
c801d85f 2287 {
1ecc4d80
RR
2288 if (GTK_WIDGET_NO_WINDOW (m_widget))
2289 {
2290 org_x += m_widget->allocation.x;
2291 org_y += m_widget->allocation.y;
2292 }
362c6693 2293 }
47d67540 2294
1ecc4d80
RR
2295 if (x) *x -= org_x;
2296 if (y) *y -= org_y;
362c6693 2297}
c801d85f 2298
debe6624 2299void wxWindow::Centre( int direction )
c801d85f 2300{
05939a81 2301 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2302
1ecc4d80
RR
2303 int x = m_x;
2304 int y = m_y;
8bbe427f 2305
1ecc4d80
RR
2306 if (m_parent)
2307 {
2308 int p_w = 0;
2309 int p_h = 0;
2310 m_parent->GetSize( &p_w, &p_h );
2311 if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (p_w - m_width) / 2;
2312 if (direction & wxVERTICAL == wxVERTICAL) y = (p_h - m_height) / 2;
2313 }
2314 else
2315 {
2316 if (direction & wxHORIZONTAL == wxHORIZONTAL) x = (gdk_screen_width () - m_width) / 2;
2317 if (direction & wxVERTICAL == wxVERTICAL) y = (gdk_screen_height () - m_height) / 2;
2318 }
8bbe427f 2319
1ecc4d80 2320 Move( x, y );
362c6693 2321}
c801d85f 2322
68dda785 2323void wxWindow::Fit()
c801d85f 2324{
05939a81 2325 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
5e0aa05a 2326
1ecc4d80
RR
2327 int maxX = 0;
2328 int maxY = 0;
2329 wxNode *node = m_children.First();
2330 while (node)
2331 {
2332 wxWindow *win = (wxWindow *)node->Data();
2333 int wx, wy, ww, wh;
2334 win->GetPosition(&wx, &wy);
2335 win->GetSize(&ww, &wh);
2336 if (wx + ww > maxX) maxX = wx + ww;
2337 if (wy + wh > maxY) maxY = wy + wh;
2338
2339 node = node->Next();
2340 }
ff8bfdbb 2341
1ecc4d80 2342 SetClientSize(maxX + 7, maxY + 14);
362c6693 2343}
c801d85f 2344
2f2aa628
RR
2345void wxWindow::SetSizeHints( int minW, int minH, int maxW, int maxH, int WXUNUSED(incW), int WXUNUSED(incH) )
2346{
05939a81 2347 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2348
1ecc4d80
RR
2349 m_minWidth = minW;
2350 m_minHeight = minH;
2351 m_maxWidth = maxW;
2352 m_maxHeight = maxH;
2f2aa628
RR
2353}
2354
c801d85f
KB
2355void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
2356{
2e563988
RR
2357 /* this is commented because it also is commented
2358 in wxMSW. before I get even more questions about
2359 this. */
f04371f0 2360// if (GetAutoLayout()) Layout();
362c6693 2361}
c801d85f 2362
debe6624 2363bool wxWindow::Show( bool show )
c801d85f 2364{
05939a81 2365 wxCHECK_MSG( (m_widget != NULL), FALSE, _T("invalid window") );
47d67540 2366
e27ce4e9
RR
2367 if (show == m_isShown) return TRUE;
2368
1ecc4d80
RR
2369 if (show)
2370 gtk_widget_show( m_widget );
2371 else
2372 gtk_widget_hide( m_widget );
ff8bfdbb 2373
1ecc4d80 2374 m_isShown = show;
ff8bfdbb 2375
1ecc4d80 2376 return TRUE;
362c6693 2377}
c801d85f 2378
debe6624 2379void wxWindow::Enable( bool enable )
c801d85f 2380{
05939a81 2381 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2382
1ecc4d80 2383 m_isEnabled = enable;
ff8bfdbb 2384
1ecc4d80
RR
2385 gtk_widget_set_sensitive( m_widget, enable );
2386 if (m_wxwindow) gtk_widget_set_sensitive( m_wxwindow, enable );
362c6693 2387}
c801d85f 2388
68dda785 2389int wxWindow::GetCharHeight() const
c33c4050 2390{
05939a81 2391 wxCHECK_MSG( (m_widget != NULL), 12, _T("invalid window") );
47d67540 2392
05939a81 2393 wxCHECK_MSG( m_font.Ok(), 12, _T("invalid font") );
47d67540 2394
1ecc4d80 2395 GdkFont *font = m_font.GetInternalFont( 1.0 );
ff8bfdbb 2396
1ecc4d80 2397 return font->ascent + font->descent;
c33c4050
RR
2398}
2399
68dda785 2400int wxWindow::GetCharWidth() const
c33c4050 2401{
05939a81 2402 wxCHECK_MSG( (m_widget != NULL), 8, _T("invalid window") );
47d67540 2403
05939a81 2404 wxCHECK_MSG( m_font.Ok(), 8, _T("invalid font") );
47d67540 2405
463c1fa1 2406 GdkFont *font = m_font.GetInternalFont( 1.0 );
ff8bfdbb 2407
463c1fa1 2408 return gdk_string_width( font, "H" );
c33c4050
RR
2409}
2410
2411void wxWindow::GetTextExtent( const wxString& string, int *x, int *y,
2412 int *descent, int *externalLeading, const wxFont *theFont, bool WXUNUSED(use16) ) const
2413{
463c1fa1
RR
2414 wxFont fontToUse = m_font;
2415 if (theFont) fontToUse = *theFont;
47d67540 2416
05939a81 2417 wxCHECK_RET( fontToUse.Ok(), _T("invalid font") );
47d67540 2418
463c1fa1 2419 GdkFont *font = fontToUse.GetInternalFont( 1.0 );
05939a81 2420 if (x) (*x) = gdk_string_width( font, string.mbc_str() );
463c1fa1
RR
2421 if (y) (*y) = font->ascent + font->descent;
2422 if (descent) (*descent) = font->descent;
2423 if (externalLeading) (*externalLeading) = 0; // ??
c33c4050
RR
2424}
2425
debe6624 2426void wxWindow::MakeModal( bool modal )
c801d85f 2427{
1ecc4d80 2428 return;
ff8bfdbb 2429
1ecc4d80
RR
2430 // Disable all other windows
2431 if (this->IsKindOf(CLASSINFO(wxDialog)) || this->IsKindOf(CLASSINFO(wxFrame)))
c801d85f 2432 {
1ecc4d80
RR
2433 wxNode *node = wxTopLevelWindows.First();
2434 while (node)
2435 {
2436 wxWindow *win = (wxWindow *)node->Data();
2437 if (win != this) win->Enable(!modal);
c801d85f 2438
1ecc4d80
RR
2439 node = node->Next();
2440 }
c801d85f 2441 }
c801d85f
KB
2442}
2443
b666df2c
RR
2444void wxWindow::OnKeyDown( wxKeyEvent &event )
2445{
2446 event.SetEventType( wxEVT_CHAR );
ff8bfdbb 2447
b666df2c
RR
2448 if (!GetEventHandler()->ProcessEvent( event ))
2449 {
2450 event.Skip();
2451 }
2452}
2453
68dda785 2454void wxWindow::SetFocus()
c801d85f 2455{
05939a81 2456 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
ff8bfdbb 2457
463c1fa1
RR
2458 GtkWidget *connect_widget = GetConnectWidget();
2459 if (connect_widget)
c801d85f 2460 {
b292e2f5 2461 if (GTK_WIDGET_CAN_FOCUS(connect_widget) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
463c1fa1
RR
2462 {
2463 gtk_widget_grab_focus (connect_widget);
2464 }
ff8bfdbb
VZ
2465 else if (GTK_IS_CONTAINER(connect_widget))
2466 {
2467 gtk_container_focus( GTK_CONTAINER(connect_widget), GTK_DIR_TAB_FORWARD );
2468 }
2469 else
2470 {
2471 }
362c6693 2472 }
362c6693 2473}
c801d85f 2474
b292e2f5
RR
2475wxWindow *wxWindow::FindFocus()
2476{
2477 return g_focusWindow;
2478}
2479
2480bool wxWindow::AcceptsFocus() const
2481{
2482 return IsEnabled() && IsShown() && m_acceptsFocus;
2483}
2484
c801d85f
KB
2485void wxWindow::AddChild( wxWindow *child )
2486{
05939a81
OK
2487 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
2488 wxCHECK_RET( (child != NULL), _T("invalid child") );
47d67540 2489
463c1fa1 2490 m_children.Append( child );
362c6693 2491}
c801d85f 2492
463c1fa1
RR
2493wxWindow *wxWindow::ReParent( wxWindow *newParent )
2494{
05939a81 2495 wxCHECK_MSG( (m_widget != NULL), (wxWindow*) NULL, _T("invalid window") );
ff8bfdbb 2496
1ecc4d80 2497 wxWindow *oldParent = GetParent();
8bbe427f 2498
1ecc4d80 2499 if (oldParent) oldParent->RemoveChild( this );
8bbe427f 2500
1ecc4d80 2501 gtk_widget_unparent( m_widget );
8bbe427f 2502
1ecc4d80
RR
2503 if (newParent)
2504 {
2505 newParent->AddChild( this );
2506 (newParent->m_insertCallback)( newParent, this );
2507 }
8bbe427f 2508
1ecc4d80 2509 return oldParent;
362c6693 2510}
c801d85f
KB
2511
2512void wxWindow::RemoveChild( wxWindow *child )
2513{
db1b4961 2514 m_children.DeleteObject( child );
463c1fa1 2515 child->m_parent = (wxWindow *) NULL;
362c6693 2516}
c801d85f
KB
2517
2518void wxWindow::SetReturnCode( int retCode )
2519{
463c1fa1 2520 m_retCode = retCode;
362c6693 2521}
c801d85f 2522
68dda785 2523int wxWindow::GetReturnCode()
c801d85f 2524{
463c1fa1 2525 return m_retCode;
362c6693 2526}
c801d85f 2527
68dda785 2528void wxWindow::Raise()
362c6693 2529{
05939a81 2530 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2531
2b07d713
RR
2532 if (!m_widget->window) return;
2533
463c1fa1 2534 if (m_widget) gdk_window_raise( m_widget->window );
362c6693
RR
2535}
2536
68dda785 2537void wxWindow::Lower()
362c6693 2538{
05939a81 2539 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2540
2b07d713
RR
2541 if (!m_widget->window) return;
2542
463c1fa1 2543 if (m_widget) gdk_window_lower( m_widget->window );
362c6693 2544}
c801d85f 2545
8bbe427f 2546wxEvtHandler *wxWindow::GetEventHandler() const
c801d85f 2547{
463c1fa1 2548 return m_eventHandler;
362c6693 2549}
c801d85f 2550
86b29a61 2551void wxWindow::SetEventHandler( wxEvtHandler *handler )
c801d85f 2552{
463c1fa1 2553 m_eventHandler = handler;
362c6693 2554}
c801d85f 2555
86b29a61
RR
2556void wxWindow::PushEventHandler(wxEvtHandler *handler)
2557{
463c1fa1
RR
2558 handler->SetNextHandler(GetEventHandler());
2559 SetEventHandler(handler);
86b29a61
RR
2560}
2561
2562wxEvtHandler *wxWindow::PopEventHandler(bool deleteHandler)
2563{
463c1fa1 2564 if (GetEventHandler())
e55ad60e 2565 {
463c1fa1
RR
2566 wxEvtHandler *handlerA = GetEventHandler();
2567 wxEvtHandler *handlerB = handlerA->GetNextHandler();
2568 handlerA->SetNextHandler((wxEvtHandler *) NULL);
2569 SetEventHandler(handlerB);
2570 if (deleteHandler)
2571 {
2572 delete handlerA;
2573 return (wxEvtHandler*) NULL;
2574 }
2575 else
2576 return handlerA;
2577 }
2578 else
2579 return (wxEvtHandler *) NULL;
86b29a61
RR
2580}
2581
68dda785 2582wxValidator *wxWindow::GetValidator()
c801d85f 2583{
463c1fa1 2584 return m_windowValidator;
362c6693 2585}
c801d85f 2586
6de97a3b 2587void wxWindow::SetValidator( const wxValidator& validator )
c801d85f 2588{
1ecc4d80 2589 if (m_windowValidator) delete m_windowValidator;
ca298c88 2590 m_windowValidator = (wxValidator*)validator.Clone();
1ecc4d80 2591 if (m_windowValidator) m_windowValidator->SetWindow(this);
362c6693 2592}
c801d85f 2593
fd0eed64
RR
2594void wxWindow::SetClientObject( wxClientData *data )
2595{
1ecc4d80
RR
2596 if (m_clientObject) delete m_clientObject;
2597 m_clientObject = data;
fd0eed64
RR
2598}
2599
2600wxClientData *wxWindow::GetClientObject()
2601{
1ecc4d80 2602 return m_clientObject;
fd0eed64
RR
2603}
2604
2605void wxWindow::SetClientData( void *data )
2606{
1ecc4d80 2607 m_clientData = data;
fd0eed64
RR
2608}
2609
2610void *wxWindow::GetClientData()
2611{
1ecc4d80 2612 return m_clientData;
fd0eed64
RR
2613}
2614
68dda785 2615bool wxWindow::IsBeingDeleted()
c801d85f 2616{
1ecc4d80 2617 return FALSE;
362c6693 2618}
c801d85f
KB
2619
2620void wxWindow::SetId( wxWindowID id )
2621{
1ecc4d80 2622 m_windowId = id;
362c6693 2623}
c801d85f 2624
8bbe427f 2625wxWindowID wxWindow::GetId() const
c801d85f 2626{
1ecc4d80 2627 return m_windowId;
362c6693 2628}
c801d85f
KB
2629
2630void wxWindow::SetCursor( const wxCursor &cursor )
2631{
05939a81 2632 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2633
1ecc4d80
RR
2634 if (cursor.Ok())
2635 {
1b3667ab
RR
2636 if (cursor == m_cursor) return;
2637 m_cursor = cursor;
1ecc4d80
RR
2638 }
2639 else
2640 {
1b3667ab 2641 m_cursor = *wxSTANDARD_CURSOR;
1ecc4d80 2642 }
a3622daa 2643
2b07d713
RR
2644 if (!m_widget->window) return;
2645
1b3667ab 2646 gdk_window_set_cursor( m_widget->window, m_cursor.GetCursor() );
47d67540 2647
1ecc4d80 2648 if ((m_wxwindow) && (m_wxwindow->window))
1b3667ab 2649 gdk_window_set_cursor( m_wxwindow->window, m_cursor.GetCursor() );
362c6693 2650}
c801d85f 2651
4f22cf8d
RR
2652void wxWindow::WarpPointer( int WXUNUSED(x), int WXUNUSED(y) )
2653{
2654 // TODO
2655}
2656
debe6624 2657void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
c801d85f 2658{
05939a81 2659 wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
47d67540 2660
2b07d713
RR
2661 if (!m_widget->window) return;
2662
139adb6a 2663 if (eraseBackground && m_wxwindow && m_wxwindow->window)
c801d85f 2664 {
139adb6a
RR
2665 if (rect)
2666 {
2667 gdk_window_clear_area( m_wxwindow->window,
2668 rect->x, rect->y,
f234c60c 2669 rect->width, rect->height );
139adb6a
RR
2670 }
2671 else
2672 {
f234c60c 2673 gdk_window_clear( m_wxwindow->window );
139adb6a
RR
2674 }
2675 }
ff8bfdbb 2676
139adb6a
RR
2677 if (!rect)
2678 {
2679 if (m_wxwindow)
2680 gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
ff8bfdbb 2681 else
139adb6a 2682 gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
362c6693 2683 }
c801d85f 2684 else
139adb6a
RR
2685 {
2686 GdkRectangle gdk_rect;
2687 gdk_rect.x = rect->x;
2688 gdk_rect.y = rect->y;
2689 gdk_rect.width = rect->width;
2690 gdk_rect.height = rect->height;
2691
2692 if (m_wxwindow)
2693 gtk_widget_draw( m_wxwindow, &gdk_rect );
2694 else
2695 gtk_widget_draw( m_widget, &gdk_rect );
2696 }
362c6693 2697}
c801d85f 2698
8429bec1
RR
2699wxRegion wxWindow::GetUpdateRegion() const
2700{
2701 return m_updateRegion;
2702}
2703
2704bool wxWindow::IsExposed( int x, int y) const
c801d85f 2705{
1ecc4d80 2706 return (m_updateRegion.Contains( x, y ) != wxOutRegion );
362c6693 2707}
c801d85f 2708
8429bec1
RR
2709bool wxWindow::IsExposed( int x, int y, int w, int h ) const
2710{
1ecc4d80 2711 return (m_updateRegion.Contains( x, y, w, h ) != wxOutRegion );
8429bec1
RR
2712}
2713
2714bool wxWindow::IsExposed( const wxPoint& pt ) const
2715{
1ecc4d80 2716 return (m_updateRegion.Contains( pt.x, pt.y ) != wxOutRegion );
8429bec1
RR
2717}
2718
2719bool wxWindow::IsExposed( const wxRect& rect ) const
c801d85f 2720{
1ecc4d80 2721 return (m_updateRegion.Contains( rect.x, rect.y, rect.width, rect.height ) != wxOutRegion );
362c6693 2722}
c801d85f 2723
68dda785 2724void wxWindow::Clear()
c801d85f 2725{
05939a81 2726 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
47d67540 2727
2b07d713
RR
2728 if (!m_widget->window) return;
2729
f234c60c
RR
2730 if (m_wxwindow && m_wxwindow->window)
2731 {
2732 gdk_window_clear( m_wxwindow->window );
2733 }
362c6693 2734}
c801d85f 2735
ff8bfdbb 2736#if wxUSE_TOOLTIPS
b1170810
RR
2737void wxWindow::SetToolTip( const wxString &tip )
2738{
301cd871
RR
2739 if (m_toolTip)
2740 {
2741 m_toolTip->SetTip( tip );
2742 }
2743 else
2744 {
ff8bfdbb 2745 SetToolTip( new wxToolTip( tip ) );
301cd871 2746 }
ff8bfdbb
VZ
2747
2748 // setting empty tooltip text does not remove the tooltip any more for
2749 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
b1170810
RR
2750}
2751
2752void wxWindow::SetToolTip( wxToolTip *tip )
2753{
301cd871
RR
2754 if (m_toolTip)
2755 {
2756 m_toolTip->SetTip( (char*) NULL );
2757 delete m_toolTip;
2758 }
ff8bfdbb 2759
b1170810 2760 m_toolTip = tip;
ff8bfdbb
VZ
2761
2762 if (m_toolTip)
2763 m_toolTip->Apply( this );
b1170810
RR
2764}
2765
05939a81 2766void wxWindow::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
b1170810 2767{
05939a81 2768 gtk_tooltips_set_tip( tips, GetConnectWidget(), wxConv_current->cWX2MB(tip), (gchar*) NULL );
301cd871 2769}
ff8bfdbb 2770#endif // wxUSE_TOOLTIPS
b1170810 2771
68dda785 2772wxColour wxWindow::GetBackgroundColour() const
c801d85f 2773{
3bc755fc 2774 return m_backgroundColour;
362c6693 2775}
c801d85f
KB
2776
2777void wxWindow::SetBackgroundColour( const wxColour &colour )
2778{
05939a81 2779 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
47d67540 2780
3bc755fc 2781 if (m_backgroundColour == colour) return;
8bbe427f 2782
3bc755fc
RR
2783 m_backgroundColour = colour;
2784 if (!m_backgroundColour.Ok()) return;
8bbe427f 2785
1e133b7d
RR
2786 GtkWidget *connect_widget = GetConnectWidget();
2787 if (!connect_widget->window) return;
ca298c88 2788
f234c60c 2789 if (m_wxwindow && m_wxwindow->window)
3bc755fc 2790 {
f234c60c 2791 /* wxMSW doesn't clear the window here. I don't do that
ca298c88 2792 either to provide compatibility. call Clear() to do
f234c60c 2793 the job. */
ca298c88 2794
f234c60c
RR
2795 m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_wxwindow->window ) );
2796 gdk_window_set_background( m_wxwindow->window, m_backgroundColour.GetColor() );
3bc755fc 2797 }
8bbe427f 2798
ae0bdb01 2799 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
ca298c88 2800
ff8bfdbb
VZ
2801 if (sysbg.Red() == colour.Red() &&
2802 sysbg.Green() == colour.Green() &&
ae0bdb01
RR
2803 sysbg.Blue() == colour.Blue())
2804 {
2805 m_backgroundColour = wxNullColour;
2806 ApplyWidgetStyle();
ff8bfdbb
VZ
2807 m_backgroundColour = sysbg;
2808 }
ae0bdb01
RR
2809 else
2810 {
2811 ApplyWidgetStyle();
2812 }
362c6693 2813}
c801d85f 2814
68dda785 2815wxColour wxWindow::GetForegroundColour() const
6de97a3b 2816{
3bc755fc 2817 return m_foregroundColour;
6de97a3b
RR
2818}
2819
2820void wxWindow::SetForegroundColour( const wxColour &colour )
2821{
05939a81 2822 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
a81258be 2823
3bc755fc 2824 if (m_foregroundColour == colour) return;
8bbe427f 2825
3bc755fc
RR
2826 m_foregroundColour = colour;
2827 if (!m_foregroundColour.Ok()) return;
8bbe427f 2828
2b07d713
RR
2829 if (!m_widget->window) return;
2830
ae0bdb01 2831 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
ff8bfdbb
VZ
2832 if (sysbg.Red() == colour.Red() &&
2833 sysbg.Green() == colour.Green() &&
ae0bdb01
RR
2834 sysbg.Blue() == colour.Blue())
2835 {
2836 m_backgroundColour = wxNullColour;
2837 ApplyWidgetStyle();
ff8bfdbb
VZ
2838 m_backgroundColour = sysbg;
2839 }
ae0bdb01
RR
2840 else
2841 {
2842 ApplyWidgetStyle();
2843 }
58614078
RR
2844}
2845
2846GtkStyle *wxWindow::GetWidgetStyle()
2847{
1ecc4d80 2848 if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
8bbe427f 2849
1ecc4d80
RR
2850 m_widgetStyle =
2851 gtk_style_copy(
2852 gtk_widget_get_style( m_widget ) );
8bbe427f 2853
1ecc4d80 2854 return m_widgetStyle;
58614078
RR
2855}
2856
2857void wxWindow::SetWidgetStyle()
2858{
1ecc4d80
RR
2859 GtkStyle *style = GetWidgetStyle();
2860
2861 gdk_font_unref( style->font );
2862 style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
2863
2864 if (m_foregroundColour.Ok())
2865 {
2866 m_foregroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2867 style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
2868 style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
2869 style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
2870 }
2871
2872 if (m_backgroundColour.Ok())
2873 {
2874 m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_widget->window ) );
2875 style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2876 style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
2877 style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2878 style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
2879 style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2880 style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
2881 style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2882 style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
2883 }
a81258be
RR
2884}
2885
58614078 2886void wxWindow::ApplyWidgetStyle()
a81258be 2887{
6de97a3b
RR
2888}
2889
68dda785 2890bool wxWindow::Validate()
c801d85f 2891{
05939a81 2892 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid window") );
47d67540 2893
1ecc4d80
RR
2894 wxNode *node = m_children.First();
2895 while (node)
2896 {
2897 wxWindow *child = (wxWindow *)node->Data();
2898 if (child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->Validate(this))
ff8bfdbb
VZ
2899 {
2900 return FALSE;
2901 }
1ecc4d80
RR
2902 node = node->Next();
2903 }
2904 return TRUE;
362c6693 2905}
c801d85f 2906
68dda785 2907bool wxWindow::TransferDataToWindow()
c801d85f 2908{
05939a81 2909 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid window") );
47d67540 2910
1ecc4d80
RR
2911 wxNode *node = m_children.First();
2912 while (node)
c801d85f 2913 {
1ecc4d80
RR
2914 wxWindow *child = (wxWindow *)node->Data();
2915 if (child->GetValidator() && /* child->GetValidator()->Ok() && */
2916 !child->GetValidator()->TransferToWindow() )
2917 {
2918 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK|wxICON_EXCLAMATION );
2919 return FALSE;
2920 }
2921 node = node->Next();
362c6693 2922 }
1ecc4d80 2923 return TRUE;
362c6693 2924}
c801d85f 2925
68dda785 2926bool wxWindow::TransferDataFromWindow()
c801d85f 2927{
05939a81 2928 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid window") );
47d67540 2929
1ecc4d80
RR
2930 wxNode *node = m_children.First();
2931 while (node)
2932 {
2933 wxWindow *child = (wxWindow *)node->Data();
2934 if ( child->GetValidator() && /* child->GetValidator()->Ok() && */ !child->GetValidator()->TransferFromWindow() )
ff8bfdbb
VZ
2935 {
2936 return FALSE;
2937 }
1ecc4d80
RR
2938 node = node->Next();
2939 }
2940 return TRUE;
362c6693 2941}
c801d85f 2942
bcf1fa6b
RR
2943void wxWindow::SetAcceleratorTable( const wxAcceleratorTable& accel )
2944{
1ecc4d80 2945 m_acceleratorTable = accel;
bcf1fa6b
RR
2946}
2947
c801d85f
KB
2948void wxWindow::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
2949{
1ecc4d80 2950 TransferDataToWindow();
362c6693 2951}
c801d85f 2952
68dda785 2953void wxWindow::InitDialog()
c801d85f 2954{
05939a81 2955 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
47d67540 2956
1ecc4d80
RR
2957 wxInitDialogEvent event(GetId());
2958 event.SetEventObject( this );
2959 GetEventHandler()->ProcessEvent(event);
362c6693 2960}
c801d85f 2961
30dea054
RR
2962static void SetInvokingWindow( wxMenu *menu, wxWindow *win )
2963{
1ecc4d80 2964 menu->SetInvokingWindow( win );
c626a8b7 2965 wxNode *node = menu->GetItems().First();
1ecc4d80
RR
2966 while (node)
2967 {
2968 wxMenuItem *menuitem = (wxMenuItem*)node->Data();
2969 if (menuitem->IsSubMenu())
2970 {
ff8bfdbb
VZ
2971 SetInvokingWindow( menuitem->GetSubMenu(), win );
2972 }
1ecc4d80
RR
2973 node = node->Next();
2974 }
362c6693 2975}
30dea054 2976
0c77152e
RR
2977static gint gs_pop_x = 0;
2978static gint gs_pop_y = 0;
2979
2980static void pop_pos_callback( GtkMenu *menu, gint *x, gint *y, wxWindow *win )
2981{
2982 win->ClientToScreen( &gs_pop_x, &gs_pop_y );
2983 *x = gs_pop_x;
2984 *y = gs_pop_y;
2985}
2986
2987bool wxWindow::PopupMenu( wxMenu *menu, int x, int y )
30dea054 2988{
05939a81 2989 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid window") );
47d67540 2990
05939a81 2991 wxCHECK_MSG( menu != NULL, FALSE, _T("invalid popup-menu") );
8bbe427f 2992
1ecc4d80 2993 SetInvokingWindow( menu, this );
ff8bfdbb 2994
631f1bfe
JS
2995 menu->UpdateUI();
2996
0c77152e
RR
2997 gs_pop_x = x;
2998 gs_pop_y = y;
ff8bfdbb 2999
1ecc4d80 3000 gtk_menu_popup(
47d67540 3001 GTK_MENU(menu->m_menu),
0c77152e
RR
3002 (GtkWidget *) NULL, // parent menu shell
3003 (GtkWidget *) NULL, // parent menu item
3004 (GtkMenuPositionFunc) pop_pos_callback,
3005 (gpointer) this, // client data
3006 0, // button used to activate it
3007 0 //gs_timeLastClick // the time of activation
47d67540 3008 );
1ecc4d80 3009 return TRUE;
30dea054
RR
3010}
3011
06cfab17 3012#if wxUSE_DRAG_AND_DROP
ac57418f 3013
c801d85f
KB
3014void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
3015{
05939a81 3016 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
47d67540 3017
1ecc4d80 3018 GtkWidget *dnd_widget = GetConnectWidget();
47d67540 3019
1ecc4d80 3020 if (m_dropTarget) m_dropTarget->UnregisterWidget( dnd_widget );
47d67540 3021
1ecc4d80
RR
3022 if (m_dropTarget) delete m_dropTarget;
3023 m_dropTarget = dropTarget;
47d67540 3024
1ecc4d80 3025 if (m_dropTarget) m_dropTarget->RegisterWidget( dnd_widget );
362c6693 3026}
c801d85f
KB
3027
3028wxDropTarget *wxWindow::GetDropTarget() const
3029{
1ecc4d80 3030 return m_dropTarget;
362c6693 3031}
c801d85f 3032
ac57418f
RR
3033#endif
3034
68dda785 3035GtkWidget* wxWindow::GetConnectWidget()
e3e65dac 3036{
1ecc4d80
RR
3037 GtkWidget *connect_widget = m_widget;
3038 if (m_wxwindow) connect_widget = m_wxwindow;
47d67540 3039
1ecc4d80 3040 return connect_widget;
e3e65dac 3041}
47d67540 3042
903f689b
RR
3043bool wxWindow::IsOwnGtkWindow( GdkWindow *window )
3044{
1ecc4d80
RR
3045 if (m_wxwindow) return (window == m_wxwindow->window);
3046 return (window == m_widget->window);
903f689b
RR
3047}
3048
c801d85f
KB
3049void wxWindow::SetFont( const wxFont &font )
3050{
05939a81 3051 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
ca298c88 3052
828f655f 3053 if (m_font == font) return;
ca298c88 3054
1ecc4d80
RR
3055 if (((wxFont*)&font)->Ok())
3056 m_font = font;
3057 else
3058 m_font = *wxSWISS_FONT;
c801d85f 3059
9c288e4d
RR
3060 if (!m_widget->window) return;
3061
ae0bdb01 3062 wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
ff8bfdbb
VZ
3063 if (sysbg.Red() == m_backgroundColour.Red() &&
3064 sysbg.Green() == m_backgroundColour.Green() &&
ae0bdb01
RR
3065 sysbg.Blue() == m_backgroundColour.Blue())
3066 {
3067 m_backgroundColour = wxNullColour;
3068 ApplyWidgetStyle();
ff8bfdbb
VZ
3069 m_backgroundColour = sysbg;
3070 }
ae0bdb01
RR
3071 else
3072 {
3073 ApplyWidgetStyle();
3074 }
362c6693 3075}
c801d85f
KB
3076
3077void wxWindow::SetWindowStyleFlag( long flag )
3078{
1ecc4d80 3079 m_windowStyle = flag;
362c6693 3080}
c801d85f 3081
68dda785 3082long wxWindow::GetWindowStyleFlag() const
c801d85f 3083{
1ecc4d80 3084 return m_windowStyle;
362c6693 3085}
c801d85f 3086
68dda785 3087void wxWindow::CaptureMouse()
c801d85f 3088{
05939a81 3089 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
47d67540 3090
05939a81 3091 wxCHECK_RET( g_capturing == FALSE, _T("CaptureMouse called twice") );
47d67540 3092
2b07d713
RR
3093 if (!m_widget->window) return;
3094
1ecc4d80
RR
3095 GtkWidget *connect_widget = GetConnectWidget();
3096 gtk_grab_add( connect_widget );
3097 gdk_pointer_grab( connect_widget->window, FALSE,
3098 (GdkEventMask)
3099 (GDK_BUTTON_PRESS_MASK |
3100 GDK_BUTTON_RELEASE_MASK |
3101 GDK_POINTER_MOTION_MASK),
ff8bfdbb
VZ
3102 (GdkWindow *) NULL,
3103 (GdkCursor *) NULL,
3104 GDK_CURRENT_TIME );
1ecc4d80 3105 g_capturing = TRUE;
362c6693 3106}
c801d85f 3107
68dda785 3108void wxWindow::ReleaseMouse()
c801d85f 3109{
05939a81 3110 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
47d67540 3111
05939a81 3112 wxCHECK_RET( g_capturing == TRUE, _T("ReleaseMouse called twice") );
47d67540 3113
2b07d713
RR
3114 if (!m_widget->window) return;
3115
1ecc4d80
RR
3116 GtkWidget *connect_widget = GetConnectWidget();
3117 gtk_grab_remove( connect_widget );
3118 gdk_pointer_ungrab ( GDK_CURRENT_TIME );
3119 g_capturing = FALSE;
362c6693 3120}
c801d85f
KB
3121
3122void wxWindow::SetTitle( const wxString &WXUNUSED(title) )
3123{
362c6693 3124}
c801d85f 3125
68dda785 3126wxString wxWindow::GetTitle() const
c801d85f 3127{
1ecc4d80 3128 return (wxString&)m_windowName;
362c6693 3129}
c801d85f 3130
68dda785 3131wxString wxWindow::GetLabel() const
c801d85f 3132{
1ecc4d80 3133 return GetTitle();
362c6693 3134}
c801d85f
KB
3135
3136void wxWindow::SetName( const wxString &name )
3137{
1ecc4d80 3138 m_windowName = name;
362c6693 3139}
c801d85f 3140
68dda785 3141wxString wxWindow::GetName() const
c801d85f 3142{
1ecc4d80 3143 return (wxString&)m_windowName;
362c6693 3144}
c801d85f 3145
68dda785 3146bool wxWindow::IsShown() const
c801d85f 3147{
1ecc4d80 3148 return m_isShown;
362c6693 3149}
c801d85f 3150
68dda785 3151bool wxWindow::IsRetained()
c801d85f 3152{
1ecc4d80 3153 return FALSE;
362c6693 3154}
c801d85f 3155
debe6624 3156wxWindow *wxWindow::FindWindow( long id )
c801d85f 3157{
1ecc4d80
RR
3158 if (id == m_windowId) return this;
3159 wxNode *node = m_children.First();
3160 while (node)
3161 {
3162 wxWindow *child = (wxWindow*)node->Data();
3163 wxWindow *res = child->FindWindow( id );
3164 if (res) return res;
3165 node = node->Next();
3166 }
3167 return (wxWindow *) NULL;
362c6693 3168}
c801d85f
KB
3169
3170wxWindow *wxWindow::FindWindow( const wxString& name )
3171{
1ecc4d80
RR
3172 if (name == m_windowName) return this;
3173 wxNode *node = m_children.First();
3174 while (node)
3175 {
3176 wxWindow *child = (wxWindow*)node->Data();
3177 wxWindow *res = child->FindWindow( name );
3178 if (res) return res;
3179 node = node->Next();
3180 }
3181 return (wxWindow *) NULL;
362c6693 3182}
c801d85f 3183
debe6624 3184void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
cb43b372 3185 int range, bool refresh )
c801d85f 3186{
05939a81 3187 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
8bbe427f 3188
05939a81 3189 wxCHECK_RET( m_wxwindow != NULL, _T("window needs client area for scrolling") );
c801d85f 3190
1ecc4d80 3191 m_hasScrolling = TRUE;
47d67540 3192
1ecc4d80 3193 if (orient == wxHORIZONTAL)
cb43b372 3194 {
1ecc4d80
RR
3195 float fpos = (float)pos;
3196 float frange = (float)range;
3197 float fthumb = (float)thumbVisible;
3198 if (fpos > frange-fthumb) fpos = frange-fthumb;
3199 if (fpos < 0.0) fpos = 0.0;
3200
3201 if ((fabs(frange-m_hAdjust->upper) < 0.2) &&
3202 (fabs(fthumb-m_hAdjust->page_size) < 0.2))
3203 {
3204 SetScrollPos( orient, pos, refresh );
3205 return;
3206 }
47d67540 3207
1ecc4d80 3208 m_oldHorizontalPos = fpos;
47d67540 3209
1ecc4d80
RR
3210 m_hAdjust->lower = 0.0;
3211 m_hAdjust->upper = frange;
3212 m_hAdjust->value = fpos;
3213 m_hAdjust->step_increment = 1.0;
3214 m_hAdjust->page_increment = (float)(wxMax(fthumb,0));
3215 m_hAdjust->page_size = fthumb;
cb43b372 3216 }
1ecc4d80
RR
3217 else
3218 {
3219 float fpos = (float)pos;
3220 float frange = (float)range;
3221 float fthumb = (float)thumbVisible;
3222 if (fpos > frange-fthumb) fpos = frange-fthumb;
3223 if (fpos < 0.0) fpos = 0.0;
3224
3225 if ((fabs(frange-m_vAdjust->upper) < 0.2) &&
3226 (fabs(fthumb-m_vAdjust->page_size) < 0.2))
3227 {
3228 SetScrollPos( orient, pos, refresh );
3229 return;
3230 }
47d67540 3231
1ecc4d80 3232 m_oldVerticalPos = fpos;
47d67540 3233
1ecc4d80
RR
3234 m_vAdjust->lower = 0.0;
3235 m_vAdjust->upper = frange;
3236 m_vAdjust->value = fpos;
3237 m_vAdjust->step_increment = 1.0;
3238 m_vAdjust->page_increment = (float)(wxMax(fthumb,0));
3239 m_vAdjust->page_size = fthumb;
3240 }
47d67540 3241
58dea4b0 3242 if (m_wxwindow)
1ecc4d80
RR
3243 {
3244 if (orient == wxHORIZONTAL)
3245 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
3246 else
3247 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "changed" );
47d67540 3248
1ecc4d80
RR
3249 gtk_widget_set_usize( m_widget, m_width, m_height );
3250 }
362c6693 3251}
c801d85f 3252
debe6624 3253void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
c801d85f 3254{
05939a81 3255 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
1ecc4d80 3256
05939a81 3257 wxCHECK_RET( m_wxwindow != NULL, _T("window needs client area for scrolling") );
1ecc4d80
RR
3258
3259 if (orient == wxHORIZONTAL)
3260 {
3261 float fpos = (float)pos;
3262 if (fpos > m_hAdjust->upper - m_hAdjust->page_size) fpos = m_hAdjust->upper - m_hAdjust->page_size;
3263 if (fpos < 0.0) fpos = 0.0;
3264 m_oldHorizontalPos = fpos;
3265
3266 if (fabs(fpos-m_hAdjust->value) < 0.2) return;
3267 m_hAdjust->value = fpos;
3268 }
3269 else
3270 {
3271 float fpos = (float)pos;
3272 if (fpos > m_vAdjust->upper - m_vAdjust->page_size) fpos = m_vAdjust->upper - m_vAdjust->page_size;
3273 if (fpos < 0.0) fpos = 0.0;
3274 m_oldVerticalPos = fpos;
ff8bfdbb 3275
1ecc4d80
RR
3276 if (fabs(fpos-m_vAdjust->value) < 0.2) return;
3277 m_vAdjust->value = fpos;
3278 }
47d67540 3279
1ecc4d80 3280 if (!m_isScrolling)
47d67540 3281 {
1ecc4d80
RR
3282 if (m_wxwindow->window)
3283 {
3284 if (orient == wxHORIZONTAL)
3285 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
3286 else
3287 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
3288 }
cb43b372 3289 }
362c6693 3290}
c801d85f 3291
debe6624 3292int wxWindow::GetScrollThumb( int orient ) const
c801d85f 3293{
05939a81 3294 wxCHECK_MSG( m_widget != NULL, 0, _T("invalid window") );
47d67540 3295
05939a81 3296 wxCHECK_MSG( m_wxwindow != NULL, 0, _T("window needs client area for scrolling") );
47d67540 3297
1ecc4d80
RR
3298 if (orient == wxHORIZONTAL)
3299 return (int)(m_hAdjust->page_size+0.5);
3300 else
3301 return (int)(m_vAdjust->page_size+0.5);
362c6693 3302}
c801d85f 3303
debe6624 3304int wxWindow::GetScrollPos( int orient ) const
c801d85f 3305{
05939a81 3306 wxCHECK_MSG( m_widget != NULL, 0, _T("invalid window") );
47d67540 3307
05939a81 3308 wxCHECK_MSG( m_wxwindow != NULL, 0, _T("window needs client area for scrolling") );
c801d85f 3309
1ecc4d80
RR
3310 if (orient == wxHORIZONTAL)
3311 return (int)(m_hAdjust->value+0.5);
3312 else
3313 return (int)(m_vAdjust->value+0.5);
362c6693 3314}
c801d85f 3315
debe6624 3316int wxWindow::GetScrollRange( int orient ) const
c801d85f 3317{
05939a81 3318 wxCHECK_MSG( m_widget != NULL, 0, _T("invalid window") );
47d67540 3319
05939a81 3320 wxCHECK_MSG( m_wxwindow != NULL, 0, _T("window needs client area for scrolling") );
c801d85f 3321
1ecc4d80
RR
3322 if (orient == wxHORIZONTAL)
3323 return (int)(m_hAdjust->upper+0.5);
3324 else
3325 return (int)(m_vAdjust->upper+0.5);
362c6693 3326}
c801d85f 3327
debe6624 3328void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
c801d85f 3329{
05939a81 3330 wxCHECK_RET( m_widget != NULL, _T("invalid window") );
47d67540 3331
05939a81 3332 wxCHECK_RET( m_wxwindow != NULL, _T("window needs client area for scrolling") );
c801d85f 3333
96d5ab4d
RR
3334 wxNode *node = m_children.First();
3335 while (node)
3336 {
3337 wxWindow *child = (wxWindow*) node->Data();
3338 child->Move( child->m_x + dx, child->m_y + dy );
3339 node = node->Next();
3340 }
3341
c801d85f
KB
3342 int cw = 0;
3343 int ch = 0;
3344 GetClientSize( &cw, &ch );
47d67540 3345
c801d85f
KB
3346 int w = cw - abs(dx);
3347 int h = ch - abs(dy);
3348 if ((h < 0) || (w < 0))
3349 {
1ecc4d80
RR
3350 Refresh();
3351 return;
362c6693 3352 }
c801d85f
KB
3353 int s_x = 0;
3354 int s_y = 0;
3355 if (dx < 0) s_x = -dx;
3356 if (dy < 0) s_y = -dy;
3357 int d_x = 0;
3358 int d_y = 0;
3359 if (dx > 0) d_x = dx;
3360 if (dy > 0) d_y = dy;
8bbe427f 3361
32e9da8b
RR
3362 if (!m_scrollGC)
3363 {
1ecc4d80
RR
3364 m_scrollGC = gdk_gc_new( m_wxwindow->window );
3365 gdk_gc_set_exposures( m_scrollGC, TRUE );
32e9da8b 3366 }
8bbe427f 3367
32e9da8b 3368 gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
1ecc4d80 3369 m_wxwindow->window, s_x, s_y, w, h );
47d67540 3370
c801d85f
KB
3371 wxRect rect;
3372 if (dx < 0) rect.x = cw+dx; else rect.x = 0;
3373 if (dy < 0) rect.y = ch+dy; else rect.y = 0;
3374 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
3375 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
47d67540 3376
c801d85f 3377 Refresh( TRUE, &rect );
362c6693 3378}
c801d85f
KB
3379
3380//-------------------------------------------------------------------------------------
3381// Layout
3382//-------------------------------------------------------------------------------------
3383
68dda785 3384wxLayoutConstraints *wxWindow::GetConstraints() const
c801d85f
KB
3385{
3386 return m_constraints;
362c6693 3387}
c801d85f
KB
3388
3389void wxWindow::SetConstraints( wxLayoutConstraints *constraints )
3390{
3391 if (m_constraints)
3392 {
3393 UnsetConstraints(m_constraints);
3394 delete m_constraints;
3395 }
3396 m_constraints = constraints;
3397 if (m_constraints)
3398 {
3399 // Make sure other windows know they're part of a 'meaningful relationship'
3400 if (m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this))
3401 m_constraints->left.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3402 if (m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this))
3403 m_constraints->top.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3404 if (m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this))
3405 m_constraints->right.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3406 if (m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this))
3407 m_constraints->bottom.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3408 if (m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this))
3409 m_constraints->width.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3410 if (m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this))
3411 m_constraints->height.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3412 if (m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this))
3413 m_constraints->centreX.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3414 if (m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this))
3415 m_constraints->centreY.GetOtherWindow()->AddConstraintReference((wxWindow *)this);
3416 }
3417;
3418}
3419;
3420
debe6624 3421void wxWindow::SetAutoLayout( bool autoLayout )
c801d85f
KB
3422{
3423 m_autoLayout = autoLayout;
362c6693 3424}
c801d85f 3425
68dda785 3426bool wxWindow::GetAutoLayout() const
c801d85f
KB
3427{
3428 return m_autoLayout;
362c6693 3429}
c801d85f 3430
68dda785 3431wxSizer *wxWindow::GetSizer() const
c801d85f
KB
3432{
3433 return m_windowSizer;
362c6693 3434}
c801d85f
KB
3435
3436void wxWindow::SetSizerParent( wxWindow *win )
3437{
3438 m_sizerParent = win;
362c6693 3439}
c801d85f 3440
68dda785 3441wxWindow *wxWindow::GetSizerParent() const
c801d85f
KB
3442{
3443 return m_sizerParent;
362c6693 3444}
c801d85f
KB
3445
3446// This removes any dangling pointers to this window
3447// in other windows' constraintsInvolvedIn lists.
3448void wxWindow::UnsetConstraints(wxLayoutConstraints *c)
3449{
3450 if (c)
3451 {
3452 if (c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this))
3453 c->left.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3454 if (c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this))
3455 c->top.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3456 if (c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this))
3457 c->right.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3458 if (c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this))
3459 c->bottom.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3460 if (c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this))
3461 c->width.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3462 if (c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this))
3463 c->height.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3464 if (c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this))
3465 c->centreX.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3466 if (c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this))
3467 c->centreY.GetOtherWindow()->RemoveConstraintReference((wxWindow *)this);
3468 }
3469}
3470
3471// Back-pointer to other windows we're involved with, so if we delete
3472// this window, we must delete any constraints we're involved with.
3473void wxWindow::AddConstraintReference(wxWindow *otherWin)
3474{
3475 if (!m_constraintsInvolvedIn)
3476 m_constraintsInvolvedIn = new wxList;
3477 if (!m_constraintsInvolvedIn->Member(otherWin))
3478 m_constraintsInvolvedIn->Append(otherWin);
3479}
3480
3481// REMOVE back-pointer to other windows we're involved with.
3482void wxWindow::RemoveConstraintReference(wxWindow *otherWin)
3483{
3484 if (m_constraintsInvolvedIn)
3485 m_constraintsInvolvedIn->DeleteObject(otherWin);
3486}
3487
3488// Reset any constraints that mention this window
68dda785 3489void wxWindow::DeleteRelatedConstraints()
c801d85f
KB
3490{
3491 if (m_constraintsInvolvedIn)
3492 {
3493 wxNode *node = m_constraintsInvolvedIn->First();
3494 while (node)
3495 {
3496 wxWindow *win = (wxWindow *)node->Data();
3497 wxNode *next = node->Next();
3498 wxLayoutConstraints *constr = win->GetConstraints();
3499
3500 // Reset any constraints involving this window
3501 if (constr)
3502 {
3503 constr->left.ResetIfWin((wxWindow *)this);
3504 constr->top.ResetIfWin((wxWindow *)this);
3505 constr->right.ResetIfWin((wxWindow *)this);
3506 constr->bottom.ResetIfWin((wxWindow *)this);
3507 constr->width.ResetIfWin((wxWindow *)this);
3508 constr->height.ResetIfWin((wxWindow *)this);
3509 constr->centreX.ResetIfWin((wxWindow *)this);
3510 constr->centreY.ResetIfWin((wxWindow *)this);
3511 }
3512 delete node;
3513 node = next;
3514 }
3515 delete m_constraintsInvolvedIn;
c67daf87 3516 m_constraintsInvolvedIn = (wxList *) NULL;
c801d85f
KB
3517 }
3518}
3519
3520void wxWindow::SetSizer(wxSizer *sizer)
3521{
3522 m_windowSizer = sizer;
3523 if (sizer)
3524 sizer->SetSizerParent((wxWindow *)this);
3525}
3526
3527/*
3528 * New version
3529 */
3530
68dda785 3531bool wxWindow::Layout()
c801d85f
KB
3532{
3533 if (GetConstraints())
3534 {
3535 int w, h;
3536 GetClientSize(&w, &h);
3537 GetConstraints()->width.SetValue(w);
3538 GetConstraints()->height.SetValue(h);
3539 }
47d67540 3540
c801d85f
KB
3541 // If top level (one sizer), evaluate the sizer's constraints.
3542 if (GetSizer())
3543 {
3544 int noChanges;
3545 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3546 GetSizer()->LayoutPhase1(&noChanges);
3547 GetSizer()->LayoutPhase2(&noChanges);
3548 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
15b24b14 3549
c801d85f
KB
3550 return TRUE;
3551 }
3552 else
3553 {
3554 // Otherwise, evaluate child constraints
3555 ResetConstraints(); // Mark all constraints as unevaluated
3556 DoPhase(1); // Just one phase need if no sizers involved
3557 DoPhase(2);
3558 SetConstraintSizes(); // Recursively set the real window sizes
3559 }
3560 return TRUE;
3561}
3562
3563
3564// Do a phase of evaluating constraints:
3565// the default behaviour. wxSizers may do a similar
3566// thing, but also impose their own 'constraints'
3567// and order the evaluation differently.
3568bool wxWindow::LayoutPhase1(int *noChanges)
3569{
3570 wxLayoutConstraints *constr = GetConstraints();
3571 if (constr)
3572 {
3573 return constr->SatisfyConstraints((wxWindow *)this, noChanges);
3574 }
3575 else
3576 return TRUE;
3577}
3578
3579bool wxWindow::LayoutPhase2(int *noChanges)
3580{
3581 *noChanges = 0;
47d67540 3582
c801d85f
KB
3583 // Layout children
3584 DoPhase(1);
3585 DoPhase(2);
3586 return TRUE;
3587}
3588
3589// Do a phase of evaluating child constraints
debe6624 3590bool wxWindow::DoPhase(int phase)
c801d85f
KB
3591{
3592 int noIterations = 0;
3593 int maxIterations = 500;
3594 int noChanges = 1;
3595 int noFailures = 0;
3596 wxList succeeded;
3597 while ((noChanges > 0) && (noIterations < maxIterations))
3598 {
3599 noChanges = 0;
3600 noFailures = 0;
8bbe427f 3601 wxNode *node = m_children.First();
c801d85f
KB
3602 while (node)
3603 {
3604 wxWindow *child = (wxWindow *)node->Data();
3605 if (!child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)))
3606 {
3607 wxLayoutConstraints *constr = child->GetConstraints();
3608 if (constr)
3609 {
3610 if (succeeded.Member(child))
3611 {
3612 }
3613 else
3614 {
3615 int tempNoChanges = 0;
3616 bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
3617 noChanges += tempNoChanges;
3618 if (success)
3619 {
3620 succeeded.Append(child);
3621 }
3622 }
3623 }
3624 }
3625 node = node->Next();
3626 }
3627 noIterations ++;
3628 }
3629 return TRUE;
3630}
3631
68dda785 3632void wxWindow::ResetConstraints()
c801d85f
KB
3633{
3634 wxLayoutConstraints *constr = GetConstraints();
3635 if (constr)
3636 {
3637 constr->left.SetDone(FALSE);
3638 constr->top.SetDone(FALSE);
3639 constr->right.SetDone(FALSE);
3640 constr->bottom.SetDone(FALSE);
3641 constr->width.SetDone(FALSE);
3642 constr->height.SetDone(FALSE);
3643 constr->centreX.SetDone(FALSE);
3644 constr->centreY.SetDone(FALSE);
3645 }
db1b4961 3646 wxNode *node = m_children.First();
c801d85f
KB
3647 while (node)
3648 {
3649 wxWindow *win = (wxWindow *)node->Data();
3650 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
3651 win->ResetConstraints();
3652 node = node->Next();
3653 }
3654}
3655
3656// Need to distinguish between setting the 'fake' size for
3657// windows and sizers, and setting the real values.
debe6624 3658void wxWindow::SetConstraintSizes(bool recurse)
c801d85f
KB
3659{
3660 wxLayoutConstraints *constr = GetConstraints();
3661 if (constr && constr->left.GetDone() && constr->right.GetDone() &&
3662 constr->width.GetDone() && constr->height.GetDone())
3663 {
3664 int x = constr->left.GetValue();
3665 int y = constr->top.GetValue();
3666 int w = constr->width.GetValue();
3667 int h = constr->height.GetValue();
3668
3669 // If we don't want to resize this window, just move it...
3670 if ((constr->width.GetRelationship() != wxAsIs) ||
3671 (constr->height.GetRelationship() != wxAsIs))
3672 {
3673 // Calls Layout() recursively. AAAGH. How can we stop that.
3674 // Simply take Layout() out of non-top level OnSizes.
3675 SizerSetSize(x, y, w, h);
3676 }
3677 else
3678 {
3679 SizerMove(x, y);
3680 }
3681 }
3682 else if (constr)
3683 {
05939a81 3684 wxChar *windowClass = this->GetClassInfo()->GetClassName();
c801d85f
KB
3685
3686 wxString winName;
05939a81
OK
3687 if (GetName() == _T(""))
3688 winName = _T("unnamed");
5e0aa05a
VZ
3689 else
3690 winName = GetName();
05939a81
OK
3691 wxLogDebug( _T("Constraint(s) not satisfied for window of type %s, name %s:\n"),
3692 (const wxChar *)windowClass,
3693 (const wxChar *)winName);
3694 if (!constr->left.GetDone()) wxLogDebug( _T(" unsatisfied 'left' constraint.\n") );
3695 if (!constr->right.GetDone()) wxLogDebug( _T(" unsatisfied 'right' constraint.\n") );
3696 if (!constr->width.GetDone()) wxLogDebug( _T(" unsatisfied 'width' constraint.\n") );
3697 if (!constr->height.GetDone()) wxLogDebug( _T(" unsatisfied 'height' constraint.\n") );
3698 wxLogDebug( _T("Please check constraints: try adding AsIs() constraints.\n") );
c801d85f
KB
3699 }
3700
3701 if (recurse)
3702 {
db1b4961 3703 wxNode *node = m_children.First();
c801d85f
KB
3704 while (node)
3705 {
3706 wxWindow *win = (wxWindow *)node->Data();
3707 if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)))
3708 win->SetConstraintSizes();
3709 node = node->Next();
3710 }
3711 }
3712}
3713
3714// This assumes that all sizers are 'on' the same
3715// window, i.e. the parent of this window.
3716void wxWindow::TransformSizerToActual(int *x, int *y) const
3717{
3718 if (!m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog)) ||
5e0aa05a 3719 m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
c801d85f 3720 return;
47d67540 3721
c801d85f
KB
3722 int xp, yp;
3723 m_sizerParent->GetPosition(&xp, &yp);
3724 m_sizerParent->TransformSizerToActual(&xp, &yp);
3725 *x += xp;
3726 *y += yp;
3727}
3728
debe6624 3729void wxWindow::SizerSetSize(int x, int y, int w, int h)
c801d85f 3730{
5e0aa05a
VZ
3731 int xx = x;
3732 int yy = y;
c801d85f
KB
3733 TransformSizerToActual(&xx, &yy);
3734 SetSize(xx, yy, w, h);
3735}
3736
debe6624 3737void wxWindow::SizerMove(int x, int y)
c801d85f 3738{
5e0aa05a
VZ
3739 int xx = x;
3740 int yy = y;
c801d85f
KB
3741 TransformSizerToActual(&xx, &yy);
3742 Move(xx, yy);
3743}
3744
3745// Only set the size/position of the constraint (if any)
debe6624 3746void wxWindow::SetSizeConstraint(int x, int y, int w, int h)
c801d85f
KB
3747{
3748 wxLayoutConstraints *constr = GetConstraints();
3749 if (constr)
3750 {
3751 if (x != -1)
3752 {
3753 constr->left.SetValue(x);
3754 constr->left.SetDone(TRUE);
3755 }
3756 if (y != -1)
3757 {
3758 constr->top.SetValue(y);
3759 constr->top.SetDone(TRUE);
3760 }
3761 if (w != -1)
3762 {
3763 constr->width.SetValue(w);
3764 constr->width.SetDone(TRUE);
3765 }
3766 if (h != -1)
3767 {
3768 constr->height.SetValue(h);
3769 constr->height.SetDone(TRUE);
3770 }
3771 }
3772}
3773
debe6624 3774void wxWindow::MoveConstraint(int x, int y)
c801d85f
KB
3775{
3776 wxLayoutConstraints *constr = GetConstraints();
3777 if (constr)
3778 {
3779 if (x != -1)
3780 {
3781 constr->left.SetValue(x);
3782 constr->left.SetDone(TRUE);
3783 }
3784 if (y != -1)
3785 {
3786 constr->top.SetValue(y);
3787 constr->top.SetDone(TRUE);
3788 }
3789 }
3790}
3791
3792void wxWindow::GetSizeConstraint(int *w, int *h) const
3793{
3794 wxLayoutConstraints *constr = GetConstraints();
3795 if (constr)
3796 {
3797 *w = constr->width.GetValue();
3798 *h = constr->height.GetValue();
3799 }
3800 else
3801 GetSize(w, h);
3802}
3803
3804void wxWindow::GetClientSizeConstraint(int *w, int *h) const
3805{
3806 wxLayoutConstraints *constr = GetConstraints();
3807 if (constr)
3808 {
3809 *w = constr->width.GetValue();
3810 *h = constr->height.GetValue();
3811 }
3812 else
3813 GetClientSize(w, h);
3814}
3815
3816void wxWindow::GetPositionConstraint(int *x, int *y) const
3817{
b292e2f5
RR
3818 wxLayoutConstraints *constr = GetConstraints();
3819 if (constr)
c801d85f
KB
3820 {
3821 *x = constr->left.GetValue();
3822 *y = constr->top.GetValue();
3823 }
3824 else
3825 GetPosition(x, y);
3826}
3827