1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "window.h"
16 #include "wx/window.h"
20 #include "wx/layout.h"
22 #include "wx/dialog.h"
23 #include "wx/msgdlg.h"
24 #ifdef wxUSE_DRAG_AND_DROP
28 #include "wx/statusbr.h"
30 #include "wx/settings.h"
37 #include "gdk/gdkprivate.h"
38 #include "gdk/gdkkeysyms.h"
39 #include "wx/gtk/win_gtk.h"
41 //-----------------------------------------------------------------------------
42 // documentation on internals
43 //-----------------------------------------------------------------------------
46 I have been asked several times about writing some documentation about
47 the GTK port of wxWindows, especially its internal structures. Obviously,
48 you cannot understand wxGTK without knowing a little about the GTK, but
49 some more information about what the wxWindow, which is the base class
50 for all other window classes, does seems required as well.
52 What does wxWindow do? It contains the common interface for the following
53 jobs of its descendants:
55 1) Define the rudimentary behaviour common to all window classes, such as
56 resizing, intercepting user input (so as to make it possible to use these
57 events for special purposes in a derived class), window names etc.
59 2) Provide the possibility to contain and manage children, if the derived
60 class is allowed to contain children, which holds true for those window
61 classes which do not display a native GTK widget. To name them, these
62 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
63 work classes are a special case and are handled a bit differently from
64 the rest. The same holds true for the wxNotebook class.
66 3) Provide the possibility to draw into a client area of a window. This,
67 too, only holds true for classes that do not display a native GTK widget
70 4) Provide the entire mechanism for scrolling widgets. This actual inter-
71 face for this is usually in wxScrolledWindow, but the GTK implementation
74 5) A multitude of helper or extra methods for special purposes, such as
75 Drag'n'Drop, managing validators etc.
77 Normally one might expect, that one wxWindows window would always correspond
78 to one GTK widget. Under GTK, there is no such allround widget that has all
79 the functionality. Moreover, the GTK defines a client area as a different
80 widget from the actual widget you are handling. Last but not least some
81 special classes (e.g. wxFrame) handle different categories of widgets and
82 still have the possibility to draw something in the client area.
83 It was therefore required to write a special purpose GTK widget, that would
84 represent a client area in the sense of wxWindows capable to do the jobs
85 2), 3) and 4). I have written this class and it resides in win_gtk.c of
88 All windows must have a widget, with which they interact with other under-
89 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
90 thw wxWindow class has a member variable called m_widget which holds a
91 pointer to this widget. When the window class represents a GTK native widget,
92 this is (in most cases) the only GTK widget the class manages. E.g. the
93 wxStatitText class handles only a GtkLabel widget a pointer to which you
94 can find in m_widget (defined in wxWindow)
96 When the class has a client area for drawing into and for containing children
97 it has to handle the client area widget (of the type GtkMyFixed, defined in
98 win_gtk.c), but there could be any number of widgets, handled by a class
99 The common rule for all windows is only, that the widget that interacts with
100 the rest of GTK must be referenced in m_widget and all other widgets must be
101 children of this widget on the GTK level. The top-most widget, which also
102 represents the client area, must be in the m_wxwindow field and must be of
105 As I said, the window classes that display a GTK native widget only have
106 one widget, so in the case of e.g. the wxButton class m_widget holds a
107 pointer to a GtkButton widget. But windows with client areas (for drawing
108 and children) have a m_widget field that is a pointer to a GtkScrolled-
109 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
110 one is (in the GTK sense) a child of the GtkScrolledWindow.
112 If the m_wxwindow field is set, then all input to this widget is inter-
113 cepted and sent to the wxWindows class. If not, all input to the widget
114 that gets pointed to by m_widget gets intercepted and sent to the class.
118 //-------------------------------------------------------------------------
119 // conditional compilation
120 //-------------------------------------------------------------------------
122 #if (GTK_MINOR_VERSION == 1)
123 #if (GTK_MICRO_VERSION >= 5)
124 #define NEW_GTK_SCROLL_CODE
128 //-----------------------------------------------------------------------------
130 //-----------------------------------------------------------------------------
134 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
135 GdkEvent
*WXUNUSED(event
),
138 printf( "FOCUS NOW AT: " );
145 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
153 char *s
= new char[tmp
.Length()+1];
155 strcpy( s
, WXSTRINGCAST tmp
);
157 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
158 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
163 //-----------------------------------------------------------------------------
165 //-----------------------------------------------------------------------------
167 extern wxList wxPendingDelete
;
168 extern wxList wxTopLevelWindows
;
169 extern bool g_blockEventsOnDrag
;
170 extern bool g_blockEventsOnScroll
;
171 static bool g_capturing
= FALSE
;
172 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
174 // hack: we need something to pass to gtk_menu_popup, so we store the time of
175 // the last click here
176 static guint32 gs_timeLastClick
= 0;
178 //-----------------------------------------------------------------------------
179 // "expose_event" (of m_wxwindow, not of m_widget)
180 //-----------------------------------------------------------------------------
182 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
184 if (!win
->HasVMT()) return;
186 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
188 gdk_event
->area
.width
,
189 gdk_event
->area
.height
);
191 if (gdk_event
->count
> 0) return;
194 printf( "OnExpose from " );
195 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
196 printf( win->GetClassInfo()->GetClassName() );
200 wxPaintEvent
event( win
->GetId() );
201 event
.SetEventObject( win
);
202 win
->GetEventHandler()->ProcessEvent( event
);
204 win
->m_updateRegion
.Clear();
207 //-----------------------------------------------------------------------------
208 // "draw" (of m_wxwindow, not of m_widget)
209 //-----------------------------------------------------------------------------
211 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
213 if (!win
->HasVMT()) return;
215 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
217 wxPaintEvent
event( win
->GetId() );
218 event
.SetEventObject( win
);
219 win
->GetEventHandler()->ProcessEvent( event
);
221 win
->m_updateRegion
.Clear();
224 //-----------------------------------------------------------------------------
225 // "key_press_event" from any window
226 //-----------------------------------------------------------------------------
228 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
230 if (!win
->HasVMT()) return FALSE
;
231 if (g_blockEventsOnDrag
) return FALSE
;
234 printf( "OnKeyPress from " );
235 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
236 printf( win->GetClassInfo()->GetClassName() );
241 switch (gdk_event
->keyval
)
243 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
244 case GDK_Tab
: key_code
= WXK_TAB
; break;
245 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
246 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
247 case GDK_Return
: key_code
= WXK_RETURN
; break;
248 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
249 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
250 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
251 case GDK_Delete
: key_code
= WXK_DELETE
; break;
252 case GDK_Home
: key_code
= WXK_HOME
; break;
253 case GDK_Left
: key_code
= WXK_LEFT
; break;
254 case GDK_Up
: key_code
= WXK_UP
; break;
255 case GDK_Right
: key_code
= WXK_RIGHT
; break;
256 case GDK_Down
: key_code
= WXK_DOWN
; break;
257 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
258 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
259 case GDK_Next
: key_code
= WXK_NEXT
; break;
260 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
261 case GDK_End
: key_code
= WXK_END
; break;
262 case GDK_Begin
: key_code
= WXK_HOME
; break;
263 case GDK_Select
: key_code
= WXK_SELECT
; break;
264 case GDK_Print
: key_code
= WXK_PRINT
; break;
265 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
266 case GDK_Insert
: key_code
= WXK_INSERT
; break;
267 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
268 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
269 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
270 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
271 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
272 case GDK_KP_Up
: key_code
= WXK_UP
; break;
273 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
274 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
275 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
276 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
277 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
278 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
279 case GDK_KP_End
: key_code
= WXK_END
; break;
280 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
281 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
282 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
283 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
284 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
285 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
286 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
287 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
288 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
289 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
290 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
291 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
292 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
293 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
294 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
295 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
296 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
297 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
298 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
299 case GDK_F1
: key_code
= WXK_F1
; break;
300 case GDK_F2
: key_code
= WXK_F2
; break;
301 case GDK_F3
: key_code
= WXK_F3
; break;
302 case GDK_F4
: key_code
= WXK_F4
; break;
303 case GDK_F5
: key_code
= WXK_F5
; break;
304 case GDK_F6
: key_code
= WXK_F6
; break;
305 case GDK_F7
: key_code
= WXK_F7
; break;
306 case GDK_F8
: key_code
= WXK_F8
; break;
307 case GDK_F9
: key_code
= WXK_F9
; break;
308 case GDK_F10
: key_code
= WXK_F10
; break;
309 case GDK_F11
: key_code
= WXK_F11
; break;
310 case GDK_F12
: key_code
= WXK_F12
; break;
313 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
314 key_code
= gdk_event
->keyval
;
318 if (!key_code
) return FALSE
;
320 wxKeyEvent
event( wxEVT_CHAR
);
321 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
322 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
323 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
324 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
325 event
.m_keyCode
= key_code
;
328 event
.SetEventObject( win
);
330 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
334 wxWindow
*ancestor
= win
;
337 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
340 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
341 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
344 ancestor
= ancestor
->GetParent();
348 // win is a control: tab can be propagated up
349 if ((!ret
) && (gdk_event
->keyval
== GDK_Tab
))
351 wxNavigationKeyEvent new_event
;
352 new_event
.SetDirection( !(gdk_event
->state
& GDK_SHIFT_MASK
) );
353 new_event
.SetWindowChange( FALSE
);
354 new_event
.SetCurrentFocus( win
);
355 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
359 // win is a panel: up can be propagated to the panel
360 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
361 (gdk_event->keyval == GDK_Up))
363 win->m_parent->SetFocus();
367 // win is a panel: left/right can be propagated to the panel
368 if ((!ret) && (win->m_wxwindow) &&
369 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
370 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
372 wxNavigationKeyEvent new_event;
373 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
374 new_event.SetCurrentFocus( win );
375 ret = win->GetEventHandler()->ProcessEvent( new_event );
381 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
387 //-----------------------------------------------------------------------------
388 // "button_press_event"
389 //-----------------------------------------------------------------------------
391 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
393 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
395 if (g_blockEventsOnDrag
) return TRUE
;
396 if (g_blockEventsOnScroll
) return TRUE
;
400 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
402 gtk_widget_grab_focus (win
->m_wxwindow
);
405 printf( "GrabFocus from " );
406 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
407 printf( win->GetClassInfo()->GetClassName() );
414 if (!win
->HasVMT()) return TRUE
;
417 printf( "OnButtonPress from " );
418 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
419 printf( win->GetClassInfo()->GetClassName() );
423 wxEventType event_type
= wxEVT_LEFT_DOWN
;
425 if (gdk_event
->button
== 1)
427 switch (gdk_event
->type
)
429 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
430 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
434 else if (gdk_event
->button
== 2)
436 switch (gdk_event
->type
)
438 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
439 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
443 else if (gdk_event
->button
== 3)
445 switch (gdk_event
->type
)
447 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
448 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
453 wxMouseEvent
event( event_type
);
454 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
455 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
456 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
457 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
458 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
459 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
460 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
462 event
.m_x
= (long)gdk_event
->x
;
463 event
.m_y
= (long)gdk_event
->y
;
465 // Some control don't have their own X window and thus cannot get
470 wxNode
*node
= win
->GetChildren().First();
473 wxWindow
*child
= (wxWindow
*)node
->Data();
475 if (child
->m_isStaticBox
)
477 // wxStaticBox is transparent in the box itself
480 int xx1
= child
->m_x
;
481 int yy1
= child
->m_y
;
482 int xx2
= child
->m_x
+ child
->m_width
;
483 int yy2
= child
->m_x
+ child
->m_height
;
486 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
488 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
490 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
492 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
495 event
.m_x
-= child
->m_x
;
496 event
.m_y
-= child
->m_y
;
503 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
504 (child
->m_x
<= event
.m_x
) &&
505 (child
->m_y
<= event
.m_y
) &&
506 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
507 (child
->m_y
+child
->m_height
>= event
.m_y
))
510 event
.m_x
-= child
->m_x
;
511 event
.m_y
-= child
->m_y
;
519 event
.SetEventObject( win
);
521 gs_timeLastClick
= gdk_event
->time
;
523 if (win
->GetEventHandler()->ProcessEvent( event
))
524 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
529 //-----------------------------------------------------------------------------
530 // "button_release_event"
531 //-----------------------------------------------------------------------------
533 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
535 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
537 if (g_blockEventsOnDrag
) return TRUE
;
538 if (g_blockEventsOnScroll
) return TRUE
;
540 if (!win
->HasVMT()) return TRUE
;
543 printf( "OnButtonRelease from " );
544 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
545 printf( win->GetClassInfo()->GetClassName() );
549 wxEventType event_type
= wxEVT_NULL
;
551 switch (gdk_event
->button
)
553 case 1: event_type
= wxEVT_LEFT_UP
; break;
554 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
555 case 3: event_type
= wxEVT_RIGHT_UP
; break;
558 wxMouseEvent
event( event_type
);
559 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
560 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
561 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
562 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
563 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
564 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
565 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
566 event
.m_x
= (long)gdk_event
->x
;
567 event
.m_y
= (long)gdk_event
->y
;
569 // Some control don't have their own X window and thus cannot get
574 wxNode
*node
= win
->GetChildren().First();
577 wxWindow
*child
= (wxWindow
*)node
->Data();
579 if (child
->m_isStaticBox
)
581 // wxStaticBox is transparent in the box itself
584 int xx1
= child
->m_x
;
585 int yy1
= child
->m_y
;
586 int xx2
= child
->m_x
+ child
->m_width
;
587 int yy2
= child
->m_x
+ child
->m_height
;
590 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
592 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
594 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
596 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
599 event
.m_x
-= child
->m_x
;
600 event
.m_y
-= child
->m_y
;
607 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
608 (child
->m_x
<= event
.m_x
) &&
609 (child
->m_y
<= event
.m_y
) &&
610 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
611 (child
->m_y
+child
->m_height
>= event
.m_y
))
614 event
.m_x
-= child
->m_x
;
615 event
.m_y
-= child
->m_y
;
623 event
.SetEventObject( win
);
625 if (win
->GetEventHandler()->ProcessEvent( event
))
626 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
631 //-----------------------------------------------------------------------------
632 // "motion_notify_event"
633 //-----------------------------------------------------------------------------
635 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
637 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
639 if (g_blockEventsOnDrag
) return TRUE
;
640 if (g_blockEventsOnScroll
) return TRUE
;
642 if (!win
->HasVMT()) return TRUE
;
645 printf( "OnMotion from " );
646 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
647 printf( win->GetClassInfo()->GetClassName() );
651 wxMouseEvent
event( wxEVT_MOTION
);
652 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
653 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
654 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
655 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
656 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
657 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
658 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
660 event
.m_x
= (long)gdk_event
->x
;
661 event
.m_y
= (long)gdk_event
->y
;
663 // Some control don't have their own X window and thus cannot get
668 wxNode
*node
= win
->GetChildren().First();
671 wxWindow
*child
= (wxWindow
*)node
->Data();
673 if (child
->m_isStaticBox
)
675 // wxStaticBox is transparent in the box itself
678 int xx1
= child
->m_x
;
679 int yy1
= child
->m_y
;
680 int xx2
= child
->m_x
+ child
->m_width
;
681 int yy2
= child
->m_x
+ child
->m_height
;
684 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
686 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
688 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
690 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
693 event
.m_x
-= child
->m_x
;
694 event
.m_y
-= child
->m_y
;
701 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
702 (child
->m_x
<= event
.m_x
) &&
703 (child
->m_y
<= event
.m_y
) &&
704 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
705 (child
->m_y
+child
->m_height
>= event
.m_y
))
708 event
.m_x
-= child
->m_x
;
709 event
.m_y
-= child
->m_y
;
717 event
.SetEventObject( win
);
719 if (win
->GetEventHandler()->ProcessEvent( event
))
720 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
725 //-----------------------------------------------------------------------------
727 //-----------------------------------------------------------------------------
729 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
731 if (g_blockEventsOnDrag
) return TRUE
;
737 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
739 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
741 printf( "SetFocus flag from " );
742 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
743 printf( win->GetClassInfo()->GetClassName() );
749 if (!win
->HasVMT()) return TRUE
;
752 printf( "OnSetFocus from " );
753 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
754 printf( win->GetClassInfo()->GetClassName() );
756 printf( WXSTRINGCAST win->GetLabel() );
760 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
761 event
.SetEventObject( win
);
763 if (win
->GetEventHandler()->ProcessEvent( event
))
764 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
769 //-----------------------------------------------------------------------------
771 //-----------------------------------------------------------------------------
773 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
775 if (g_blockEventsOnDrag
) return TRUE
;
778 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
779 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
782 if (!win
->HasVMT()) return TRUE
;
785 printf( "OnKillFocus from " );
786 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
787 printf( win->GetClassInfo()->GetClassName() );
791 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
792 event
.SetEventObject( win
);
794 if (win
->GetEventHandler()->ProcessEvent( event
))
795 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
800 //-----------------------------------------------------------------------------
801 // "enter_notify_event"
802 //-----------------------------------------------------------------------------
804 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
806 if (g_blockEventsOnDrag
) return TRUE
;
808 if ((widget
->window
) && (win
->m_cursor
))
809 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
811 if (widget
->window
!= gdk_event
->window
) return TRUE
;
813 if (!win
->HasVMT()) return TRUE
;
816 printf( "OnEnter from " );
817 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
818 printf( win->GetClassInfo()->GetClassName() );
822 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
823 event
.SetEventObject( win
);
827 GdkModifierType state
= (GdkModifierType
)0;
829 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
831 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
832 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
833 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
834 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
835 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
836 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
837 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
842 if (win
->GetEventHandler()->ProcessEvent( event
))
843 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
848 //-----------------------------------------------------------------------------
849 // "leave_notify_event"
850 //-----------------------------------------------------------------------------
852 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
854 if (g_blockEventsOnDrag
) return TRUE
;
856 if ((widget
->window
) && (win
->m_cursor
))
857 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
859 if (widget
->window
!= gdk_event
->window
) return TRUE
;
861 if (!win
->HasVMT()) return TRUE
;
864 printf( "OnLeave from " );
865 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
866 printf( win->GetClassInfo()->GetClassName() );
870 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
871 event
.SetEventObject( win
);
875 GdkModifierType state
= (GdkModifierType
)0;
877 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
879 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
880 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
881 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
882 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
883 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
884 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
885 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
890 if (win
->GetEventHandler()->ProcessEvent( event
))
891 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
896 //-----------------------------------------------------------------------------
897 // "value_changed" from m_vAdjust
898 //-----------------------------------------------------------------------------
900 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
902 if (g_blockEventsOnDrag
) return;
905 printf( "OnVScroll from " );
906 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
907 printf( win->GetClassInfo()->GetClassName() );
911 if (!win
->HasVMT()) return;
913 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
914 if (fabs(diff
) < 0.2) return;
916 wxEventType command
= wxEVT_NULL
;
918 float line_step
= win
->m_vAdjust
->step_increment
;
919 float page_step
= win
->m_vAdjust
->page_increment
;
921 if (win
->m_isScrolling
)
923 command
= wxEVT_SCROLL_THUMBTRACK
;
927 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
928 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
929 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
930 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
931 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
932 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
933 else command
= wxEVT_SCROLL_THUMBTRACK
;
936 int value
= (int)(win
->m_vAdjust
->value
+0.5);
938 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
939 event
.SetEventObject( win
);
940 win
->GetEventHandler()->ProcessEvent( event
);
943 //-----------------------------------------------------------------------------
944 // "value_changed" from m_hAdjust
945 //-----------------------------------------------------------------------------
947 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
949 if (g_blockEventsOnDrag
) return;
952 printf( "OnHScroll from " );
953 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
954 printf( win->GetClassInfo()->GetClassName() );
958 if (!win
->HasVMT()) return;
960 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
961 if (fabs(diff
) < 0.2) return;
963 wxEventType command
= wxEVT_NULL
;
965 float line_step
= win
->m_hAdjust
->step_increment
;
966 float page_step
= win
->m_hAdjust
->page_increment
;
968 if (win
->m_isScrolling
)
970 command
= wxEVT_SCROLL_THUMBTRACK
;
974 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
975 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
976 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
977 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
978 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
979 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
980 else command
= wxEVT_SCROLL_THUMBTRACK
;
983 int value
= (int)(win
->m_hAdjust
->value
+0.5);
985 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
986 event
.SetEventObject( win
);
987 win
->GetEventHandler()->ProcessEvent( event
);
990 //-----------------------------------------------------------------------------
991 // "changed" from m_vAdjust
992 //-----------------------------------------------------------------------------
994 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
996 if (g_blockEventsOnDrag
) return;
999 printf( "OnVScroll change from " );
1000 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1001 printf( win->GetClassInfo()->GetClassName() );
1005 if (!win
->HasVMT()) return;
1007 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1008 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1010 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1011 event
.SetEventObject( win
);
1012 win
->GetEventHandler()->ProcessEvent( event
);
1015 //-----------------------------------------------------------------------------
1016 // "changed" from m_hAdjust
1017 //-----------------------------------------------------------------------------
1019 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1021 if (g_blockEventsOnDrag
) return;
1024 printf( "OnHScroll change from " );
1025 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1026 printf( win->GetClassInfo()->GetClassName() );
1030 if (!win
->HasVMT()) return;
1032 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1033 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1035 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1036 event
.SetEventObject( win
);
1037 win
->GetEventHandler()->ProcessEvent( event
);
1040 //-----------------------------------------------------------------------------
1041 // "button_press_event" from scrollbar
1042 //-----------------------------------------------------------------------------
1044 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1045 GdkEventButton
*WXUNUSED(gdk_event
),
1048 // don't test here as we can release the mouse while being over
1049 // a different window then the slider
1051 // if (gdk_event->window != widget->slider) return FALSE;
1053 win
->m_isScrolling
= TRUE
;
1054 g_blockEventsOnScroll
= TRUE
;
1059 //-----------------------------------------------------------------------------
1060 // "button_release_event" from scrollbar
1061 //-----------------------------------------------------------------------------
1063 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1064 GdkEventButton
*WXUNUSED(gdk_event
),
1068 // don't test here as we can release the mouse while being over
1069 // a different window then the slider
1071 // if (gdk_event->window != widget->slider) return FALSE;
1073 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1075 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1076 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1078 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1080 win
->m_isScrolling
= FALSE
;
1081 g_blockEventsOnScroll
= FALSE
;
1086 //-----------------------------------------------------------------------------
1087 // InsertChild for wxWindow.
1088 //-----------------------------------------------------------------------------
1090 // Callback for wxWindow. This very strange beast has to be used because
1091 // C++ has no virtual methods in a constructor. We have to emulate a
1092 // virtual function here as wxNotebook requires a different way to insert
1093 // a child in it. I had opted for creating a wxNotebookPage window class
1094 // which would have made this superfluous (such in the MDI window system),
1095 // but no-one was listening to me...
1097 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1099 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1100 GTK_WIDGET(child
->m_widget
),
1104 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1109 //-----------------------------------------------------------------------------
1111 //-----------------------------------------------------------------------------
1113 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1115 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1116 EVT_SIZE(wxWindow::OnSize
)
1117 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1118 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1119 EVT_IDLE(wxWindow::OnIdle
)
1122 wxWindow::wxWindow()
1124 m_widget
= (GtkWidget
*) NULL
;
1125 m_wxwindow
= (GtkWidget
*) NULL
;
1126 m_parent
= (wxWindow
*) NULL
;
1127 m_children
.DeleteContents( FALSE
);
1140 m_eventHandler
= this;
1141 m_windowValidator
= (wxValidator
*) NULL
;
1145 m_cursor
= (wxCursor
*) NULL
;
1146 m_font
= *wxSWISS_FONT
;
1148 m_windowName
= "noname";
1150 m_constraints
= (wxLayoutConstraints
*) NULL
;
1151 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1152 m_windowSizer
= (wxSizer
*) NULL
;
1153 m_sizerParent
= (wxWindow
*) NULL
;
1154 m_autoLayout
= FALSE
;
1158 m_needParent
= TRUE
;
1160 m_hasScrolling
= FALSE
;
1161 m_isScrolling
= FALSE
;
1162 m_hAdjust
= (GtkAdjustment
*) NULL
;
1163 m_vAdjust
= (GtkAdjustment
*) NULL
;
1164 m_oldHorizontalPos
= 0.0;
1165 m_oldVerticalPos
= 0.0;
1170 #ifdef wxUSE_DRAG_AND_DROP
1171 m_dropTarget
= (wxDropTarget
*) NULL
;
1174 m_scrollGC
= (GdkGC
*) NULL
;
1175 m_widgetStyle
= (GtkStyle
*) NULL
;
1177 m_insertCallback
= wxInsertChildInWindow
;
1179 m_clientObject
= (wxClientData
*) NULL
;
1180 m_clientData
= NULL
;
1182 m_isStaticBox
= FALSE
;
1183 m_acceptsFocus
= FALSE
;
1186 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1187 const wxPoint
&pos
, const wxSize
&size
,
1188 long style
, const wxString
&name
)
1190 m_insertCallback
= wxInsertChildInWindow
;
1191 Create( parent
, id
, pos
, size
, style
, name
);
1194 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1195 const wxPoint
&pos
, const wxSize
&size
,
1196 long style
, const wxString
&name
)
1200 m_needParent
= TRUE
;
1202 PreCreation( parent
, id
, pos
, size
, style
, name
);
1204 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1205 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1208 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1211 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1214 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1215 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1218 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1219 scroll_class
->scrollbar_spacing
= 0;
1221 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1223 m_oldHorizontalPos
= 0.0;
1224 m_oldVerticalPos
= 0.0;
1226 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1227 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1229 m_wxwindow
= gtk_myfixed_new();
1232 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1235 #ifdef NEW_GTK_SCROLL_CODE
1236 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1237 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1239 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1240 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1244 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1247 if (m_windowStyle
& wxRAISED_BORDER
)
1249 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1251 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1253 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1257 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1260 if ((m_windowStyle
& wxTAB_TRAVERSAL
) != 0)
1262 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1263 m_acceptsFocus
= FALSE
;
1267 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1268 m_acceptsFocus
= TRUE
;
1271 // shut the viewport up
1272 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1273 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1275 // I _really_ don't want scrollbars in the beginning
1276 m_vAdjust
->lower
= 0.0;
1277 m_vAdjust
->upper
= 1.0;
1278 m_vAdjust
->value
= 0.0;
1279 m_vAdjust
->step_increment
= 1.0;
1280 m_vAdjust
->page_increment
= 1.0;
1281 m_vAdjust
->page_size
= 5.0;
1282 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1283 m_hAdjust
->lower
= 0.0;
1284 m_hAdjust
->upper
= 1.0;
1285 m_hAdjust
->value
= 0.0;
1286 m_hAdjust
->step_increment
= 1.0;
1287 m_hAdjust
->page_increment
= 1.0;
1288 m_hAdjust
->page_size
= 5.0;
1289 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1291 // these handlers block mouse events to any window during scrolling
1292 // such as motion events and prevent GTK and wxWindows from fighting
1293 // over where the slider should be
1295 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1296 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1298 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1299 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1301 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1302 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1304 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1305 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1307 // these handers het notified when screen updates are required either when
1308 // scrolling or when the window size (and therefore scrollbar configuration)
1311 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1312 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1313 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1314 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1316 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1317 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1318 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1319 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1321 gtk_widget_show( m_wxwindow
);
1323 if (m_parent
) m_parent
->AddChild( this );
1325 (m_parent
->m_insertCallback
)( m_parent
, this );
1334 wxWindow::~wxWindow()
1338 #ifdef wxUSE_DRAG_AND_DROP
1339 if (m_dropTarget
) delete m_dropTarget
;
1342 if (m_parent
) m_parent
->RemoveChild( this );
1343 if (m_widget
) Show( FALSE
);
1347 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1349 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1351 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1353 if (m_widget
) gtk_widget_destroy( m_widget
);
1355 if (m_cursor
) delete m_cursor
;
1357 DeleteRelatedConstraints();
1360 // This removes any dangling pointers to this window
1361 // in other windows' constraintsInvolvedIn lists.
1362 UnsetConstraints(m_constraints
);
1363 delete m_constraints
;
1364 m_constraints
= (wxLayoutConstraints
*) NULL
;
1368 delete m_windowSizer
;
1369 m_windowSizer
= (wxSizer
*) NULL
;
1371 // If this is a child of a sizer, remove self from parent
1372 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1374 // Just in case the window has been Closed, but
1375 // we're then deleting immediately: don't leave
1376 // dangling pointers.
1377 wxPendingDelete
.DeleteObject(this);
1379 // Just in case we've loaded a top-level window via
1380 // wxWindow::LoadNativeDialog but we weren't a dialog
1382 wxTopLevelWindows
.DeleteObject(this);
1384 if (m_windowValidator
) delete m_windowValidator
;
1386 if (m_clientObject
) delete m_clientObject
;
1389 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1390 const wxPoint
&pos
, const wxSize
&size
,
1391 long style
, const wxString
&name
)
1393 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1395 m_widget
= (GtkWidget
*) NULL
;
1396 m_wxwindow
= (GtkWidget
*) NULL
;
1399 m_children
.DeleteContents( FALSE
);
1402 if (m_width
== -1) m_width
= 20;
1404 if (m_height
== -1) m_height
= 20;
1409 if (!m_needParent
) // some reasonable defaults
1413 m_x
= (gdk_screen_width () - m_width
) / 2;
1414 if (m_x
< 10) m_x
= 10;
1418 m_y
= (gdk_screen_height () - m_height
) / 2;
1419 if (m_y
< 10) m_y
= 10;
1430 m_eventHandler
= this;
1432 m_windowId
= id
== -1 ? wxNewId() : id
;
1436 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1437 m_font
= *wxSWISS_FONT
;
1438 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1439 m_foregroundColour
= *wxBLACK
;
1440 m_windowStyle
= style
;
1441 m_windowName
= name
;
1443 m_constraints
= (wxLayoutConstraints
*) NULL
;
1444 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1445 m_windowSizer
= (wxSizer
*) NULL
;
1446 m_sizerParent
= (wxWindow
*) NULL
;
1447 m_autoLayout
= FALSE
;
1449 m_hasScrolling
= FALSE
;
1450 m_isScrolling
= FALSE
;
1451 m_hAdjust
= (GtkAdjustment
*) NULL
;
1452 m_vAdjust
= (GtkAdjustment
*) NULL
;
1453 m_oldHorizontalPos
= 0.0;
1454 m_oldVerticalPos
= 0.0;
1459 #ifdef wxUSE_DRAG_AND_DROP
1460 m_dropTarget
= (wxDropTarget
*) NULL
;
1463 m_windowValidator
= (wxValidator
*) NULL
;
1464 m_scrollGC
= (GdkGC
*) NULL
;
1465 m_widgetStyle
= (GtkStyle
*) NULL
;
1467 m_clientObject
= (wxClientData
*)NULL
;
1468 m_clientData
= NULL
;
1470 m_isStaticBox
= FALSE
;
1473 void wxWindow::PostCreation()
1477 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1478 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1480 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1481 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1484 ConnectWidget( GetConnectWidget() );
1486 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1488 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1490 SetCursor( *wxSTANDARD_CURSOR
);
1495 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1497 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1498 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1500 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1501 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1503 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1504 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1506 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1507 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1509 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1510 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1512 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1513 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1515 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1516 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1518 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1519 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1522 bool wxWindow::HasVMT()
1527 bool wxWindow::Close( bool force
)
1529 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1531 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1532 event
.SetEventObject(this);
1533 event
.SetForce(force
);
1535 return GetEventHandler()->ProcessEvent(event
);
1538 bool wxWindow::Destroy()
1540 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1547 bool wxWindow::DestroyChildren()
1550 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1553 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1556 if (m_children
.Member(child
)) delete node
;
1562 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1564 // are we to set fonts here ?
1567 wxPoint
wxWindow::GetClientAreaOrigin() const
1569 return wxPoint(0,0);
1572 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1574 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1576 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1582 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1584 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1585 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1587 if (m_resizing
) return; // I don't like recursions
1590 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1592 // don't set the size for children of wxNotebook, just take the values.
1600 int old_width
= m_width
;
1601 int old_height
= m_height
;
1603 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1605 if (x
!= -1) m_x
= x
;
1606 if (y
!= -1) m_y
= y
;
1607 if (width
!= -1) m_width
= width
;
1608 if (height
!= -1) m_height
= height
;
1618 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1620 if (width
== -1) m_width
= 80;
1623 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1625 if (height
== -1) m_height
= 26;
1628 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1629 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1630 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1631 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1633 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1634 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1636 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1637 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1642 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1643 event
.SetEventObject( this );
1644 GetEventHandler()->ProcessEvent( event
);
1649 void wxWindow::SetSize( int width
, int height
)
1651 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1654 void wxWindow::Move( int x
, int y
)
1656 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1659 void wxWindow::GetSize( int *width
, int *height
) const
1661 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1663 if (width
) (*width
) = m_width
;
1664 if (height
) (*height
) = m_height
;
1667 void wxWindow::SetClientSize( int width
, int height
)
1669 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1673 SetSize( width
, height
);
1680 if (!m_hasScrolling
)
1682 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1684 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1685 (m_windowStyle
& wxSUNKEN_BORDER
))
1687 dw
+= 2 * window_class
->xthickness
;
1688 dh
+= 2 * window_class
->ythickness
;
1693 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1694 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1696 #ifdef NEW_GTK_SCROLL_CODE
1697 GtkWidget
*viewport
= scroll_window
->child
;
1699 GtkWidget
*viewport
= scroll_window
->viewport
;
1702 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1704 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1705 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1707 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1708 (m_windowStyle
& wxSUNKEN_BORDER
))
1710 dw
+= 2 * viewport_class
->xthickness
;
1711 dh
+= 2 * viewport_class
->ythickness
;
1714 if (scroll_window
->vscrollbar_visible
)
1716 dw
+= vscrollbar
->allocation
.width
;
1717 dw
+= scroll_class
->scrollbar_spacing
;
1720 if (scroll_window
->hscrollbar_visible
)
1722 dh
+= hscrollbar
->allocation
.height
;
1723 dw
+= scroll_class
->scrollbar_spacing
;
1727 SetSize( width
+dw
, height
+dh
);
1731 void wxWindow::GetClientSize( int *width
, int *height
) const
1733 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1737 if (width
) (*width
) = m_width
;
1738 if (height
) (*height
) = m_height
;
1745 if (!m_hasScrolling
)
1747 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1749 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1750 (m_windowStyle
& wxSUNKEN_BORDER
))
1752 dw
+= 2 * window_class
->xthickness
;
1753 dh
+= 2 * window_class
->ythickness
;
1758 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1759 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1761 #ifdef NEW_GTK_SCROLL_CODE
1762 GtkWidget
*viewport
= scroll_window
->child
;
1764 GtkWidget
*viewport
= scroll_window
->viewport
;
1767 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1769 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1770 (m_windowStyle
& wxSUNKEN_BORDER
))
1772 dw
+= 2 * viewport_class
->xthickness
;
1773 dh
+= 2 * viewport_class
->ythickness
;
1776 if (scroll_window
->vscrollbar_visible
)
1778 // dw += vscrollbar->allocation.width;
1779 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1780 dw
+= scroll_class
->scrollbar_spacing
;
1783 if (scroll_window
->hscrollbar_visible
)
1785 // dh += hscrollbar->allocation.height;
1787 dh
+= scroll_class
->scrollbar_spacing
;
1791 if (width
) (*width
) = m_width
- dw
;
1792 if (height
) (*height
) = m_height
- dh
;
1796 void wxWindow::GetPosition( int *x
, int *y
) const
1798 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1804 void wxWindow::ClientToScreen( int *x
, int *y
)
1806 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1808 GdkWindow
*source
= (GdkWindow
*) NULL
;
1810 source
= m_wxwindow
->window
;
1812 source
= m_widget
->window
;
1816 gdk_window_get_origin( source
, &org_x
, &org_y
);
1820 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1822 org_x
+= m_widget
->allocation
.x
;
1823 org_y
+= m_widget
->allocation
.y
;
1827 wxPoint
pt(GetClientAreaOrigin());
1835 void wxWindow::ScreenToClient( int *x
, int *y
)
1837 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1839 GdkWindow
*source
= (GdkWindow
*) NULL
;
1841 source
= m_wxwindow
->window
;
1843 source
= m_widget
->window
;
1847 gdk_window_get_origin( source
, &org_x
, &org_y
);
1851 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1853 org_x
+= m_widget
->allocation
.x
;
1854 org_y
+= m_widget
->allocation
.y
;
1858 wxPoint
pt(GetClientAreaOrigin());
1866 void wxWindow::Centre( int direction
)
1868 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1877 m_parent
->GetSize( &p_w
, &p_h
);
1878 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
1879 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
1883 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
1884 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
1890 void wxWindow::Fit()
1892 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1896 wxNode
*node
= m_children
.First();
1899 wxWindow
*win
= (wxWindow
*)node
->Data();
1901 win
->GetPosition(&wx
, &wy
);
1902 win
->GetSize(&ww
, &wh
);
1903 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
1904 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
1906 node
= node
->Next();
1909 SetClientSize(maxX
+ 7, maxY
+ 14);
1912 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1914 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1922 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1924 // if (GetAutoLayout()) Layout();
1927 bool wxWindow::Show( bool show
)
1929 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
1932 gtk_widget_show( m_widget
);
1934 gtk_widget_hide( m_widget
);
1941 void wxWindow::Enable( bool enable
)
1943 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1945 m_isEnabled
= enable
;
1947 gtk_widget_set_sensitive( m_widget
, enable
);
1948 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1951 int wxWindow::GetCharHeight() const
1953 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
1955 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
1957 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1959 return font
->ascent
+ font
->descent
;
1962 int wxWindow::GetCharWidth() const
1964 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
1966 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
1968 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1970 return gdk_string_width( font
, "H" );
1973 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1974 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1976 wxFont fontToUse
= m_font
;
1977 if (theFont
) fontToUse
= *theFont
;
1979 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
1981 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1982 if (x
) (*x
) = gdk_string_width( font
, string
);
1983 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1984 if (descent
) (*descent
) = font
->descent
;
1985 if (externalLeading
) (*externalLeading
) = 0; // ??
1988 void wxWindow::MakeModal( bool modal
)
1992 // Disable all other windows
1993 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1995 wxNode
*node
= wxTopLevelWindows
.First();
1998 wxWindow
*win
= (wxWindow
*)node
->Data();
1999 if (win
!= this) win
->Enable(!modal
);
2001 node
= node
->Next();
2006 void wxWindow::SetFocus()
2008 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2010 GtkWidget
*connect_widget
= GetConnectWidget();
2013 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2015 gtk_widget_grab_focus (connect_widget
);
2017 else if (GTK_IS_CONTAINER(connect_widget
))
2019 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2027 wxWindow
*wxWindow::FindFocus()
2029 return g_focusWindow
;
2032 bool wxWindow::AcceptsFocus() const
2034 return IsEnabled() && IsShown() && m_acceptsFocus
;
2037 bool wxWindow::OnClose()
2042 void wxWindow::AddChild( wxWindow
*child
)
2044 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2045 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2047 m_children
.Append( child
);
2050 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2052 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2054 wxWindow
*oldParent
= GetParent();
2056 if (oldParent
) oldParent
->RemoveChild( this );
2058 gtk_widget_unparent( m_widget
);
2062 newParent
->AddChild( this );
2063 (newParent
->m_insertCallback
)( newParent
, this );
2069 void wxWindow::RemoveChild( wxWindow
*child
)
2071 m_children
.DeleteObject( child
);
2072 child
->m_parent
= (wxWindow
*) NULL
;
2075 void wxWindow::SetReturnCode( int retCode
)
2077 m_retCode
= retCode
;
2080 int wxWindow::GetReturnCode()
2085 void wxWindow::Raise()
2087 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2089 if (m_widget
) gdk_window_raise( m_widget
->window
);
2092 void wxWindow::Lower()
2094 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2096 if (m_widget
) gdk_window_lower( m_widget
->window
);
2099 wxEvtHandler
*wxWindow::GetEventHandler() const
2101 return m_eventHandler
;
2104 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2106 m_eventHandler
= handler
;
2109 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2111 handler
->SetNextHandler(GetEventHandler());
2112 SetEventHandler(handler
);
2115 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2117 if (GetEventHandler())
2119 wxEvtHandler
*handlerA
= GetEventHandler();
2120 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2121 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2122 SetEventHandler(handlerB
);
2126 return (wxEvtHandler
*) NULL
;
2132 return (wxEvtHandler
*) NULL
;
2135 wxValidator
*wxWindow::GetValidator()
2137 return m_windowValidator
;
2140 void wxWindow::SetValidator( const wxValidator
& validator
)
2142 if (m_windowValidator
) delete m_windowValidator
;
2143 m_windowValidator
= validator
.Clone();
2144 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2147 void wxWindow::SetClientObject( wxClientData
*data
)
2149 if (m_clientObject
) delete m_clientObject
;
2150 m_clientObject
= data
;
2153 wxClientData
*wxWindow::GetClientObject()
2155 return m_clientObject
;
2158 void wxWindow::SetClientData( void *data
)
2160 m_clientData
= data
;
2163 void *wxWindow::GetClientData()
2165 return m_clientData
;
2168 bool wxWindow::IsBeingDeleted()
2173 void wxWindow::SetId( wxWindowID id
)
2178 wxWindowID
wxWindow::GetId() const
2183 void wxWindow::SetCursor( const wxCursor
&cursor
)
2185 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2189 if (cursor
== *m_cursor
) return;
2194 *m_cursor
= *wxSTANDARD_CURSOR
;
2197 if ((m_widget
) && (m_widget
->window
))
2198 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2200 if ((m_wxwindow
) && (m_wxwindow
->window
))
2201 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2204 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2209 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2211 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2213 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2217 gdk_window_clear_area( m_wxwindow
->window
,
2231 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2233 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2237 GdkRectangle gdk_rect
;
2238 gdk_rect
.x
= rect
->x
;
2239 gdk_rect
.y
= rect
->y
;
2240 gdk_rect
.width
= rect
->width
;
2241 gdk_rect
.height
= rect
->height
;
2244 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2246 gtk_widget_draw( m_widget
, &gdk_rect
);
2250 wxRegion
wxWindow::GetUpdateRegion() const
2252 return m_updateRegion
;
2255 bool wxWindow::IsExposed( int x
, int y
) const
2257 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2260 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2262 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2265 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2267 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2270 bool wxWindow::IsExposed( const wxRect
& rect
) const
2272 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2275 void wxWindow::Clear()
2277 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2279 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2282 wxColour
wxWindow::GetBackgroundColour() const
2284 return m_backgroundColour
;
2287 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2289 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2291 if (m_backgroundColour
== colour
) return;
2293 m_backgroundColour
= colour
;
2294 if (!m_backgroundColour
.Ok()) return;
2298 GdkWindow
*window
= m_wxwindow
->window
;
2299 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2300 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2301 gdk_window_clear( window
);
2304 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2305 if (sysbg
.Red() == colour
.Red() &&
2306 sysbg
.Green() == colour
.Green() &&
2307 sysbg
.Blue() == colour
.Blue())
2309 m_backgroundColour
= wxNullColour
;
2311 m_backgroundColour
= sysbg
;
2319 wxColour
wxWindow::GetForegroundColour() const
2321 return m_foregroundColour
;
2324 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2326 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2328 if (m_foregroundColour
== colour
) return;
2330 m_foregroundColour
= colour
;
2331 if (!m_foregroundColour
.Ok()) return;
2333 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2334 if (sysbg
.Red() == colour
.Red() &&
2335 sysbg
.Green() == colour
.Green() &&
2336 sysbg
.Blue() == colour
.Blue())
2338 m_backgroundColour
= wxNullColour
;
2340 m_backgroundColour
= sysbg
;
2348 GtkStyle
*wxWindow::GetWidgetStyle()
2350 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2354 gtk_widget_get_style( m_widget
) );
2356 return m_widgetStyle
;
2359 void wxWindow::SetWidgetStyle()
2361 GtkStyle
*style
= GetWidgetStyle();
2363 gdk_font_unref( style
->font
);
2364 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2366 if (m_foregroundColour
.Ok())
2368 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2369 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2370 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2371 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2374 if (m_backgroundColour
.Ok())
2376 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2377 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2378 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2379 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2380 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2381 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2382 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2383 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2384 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2388 void wxWindow::ApplyWidgetStyle()
2392 bool wxWindow::Validate()
2394 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2396 wxNode
*node
= m_children
.First();
2399 wxWindow
*child
= (wxWindow
*)node
->Data();
2400 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2404 node
= node
->Next();
2409 bool wxWindow::TransferDataToWindow()
2411 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2413 wxNode
*node
= m_children
.First();
2416 wxWindow
*child
= (wxWindow
*)node
->Data();
2417 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2418 !child
->GetValidator()->TransferToWindow() )
2420 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2423 node
= node
->Next();
2428 bool wxWindow::TransferDataFromWindow()
2430 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2432 wxNode
*node
= m_children
.First();
2435 wxWindow
*child
= (wxWindow
*)node
->Data();
2436 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2440 node
= node
->Next();
2445 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2447 m_acceleratorTable
= accel
;
2450 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2452 TransferDataToWindow();
2455 void wxWindow::InitDialog()
2457 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2459 wxInitDialogEvent
event(GetId());
2460 event
.SetEventObject( this );
2461 GetEventHandler()->ProcessEvent(event
);
2464 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2466 menu
->SetInvokingWindow( win
);
2467 wxNode
*node
= menu
->m_items
.First();
2470 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2471 if (menuitem
->IsSubMenu())
2473 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2475 node
= node
->Next();
2479 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2481 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2483 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2485 SetInvokingWindow( menu
, this );
2487 GTK_MENU(menu
->m_menu
),
2488 (GtkWidget
*)NULL
, // parent menu shell
2489 (GtkWidget
*)NULL
, // parent menu item
2490 (GtkMenuPositionFunc
)NULL
,
2491 NULL
, // client data
2492 0, // button used to activate it
2493 0//gs_timeLastClick // the time of activation
2498 #ifdef wxUSE_DRAG_AND_DROP
2500 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2502 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2504 GtkWidget
*dnd_widget
= GetConnectWidget();
2506 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2508 if (m_dropTarget
) delete m_dropTarget
;
2509 m_dropTarget
= dropTarget
;
2511 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2514 wxDropTarget
*wxWindow::GetDropTarget() const
2516 return m_dropTarget
;
2521 GtkWidget
* wxWindow::GetConnectWidget()
2523 GtkWidget
*connect_widget
= m_widget
;
2524 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2526 return connect_widget
;
2529 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2531 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2532 return (window
== m_widget
->window
);
2535 void wxWindow::SetFont( const wxFont
&font
)
2537 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2539 if (((wxFont
*)&font
)->Ok())
2542 m_font
= *wxSWISS_FONT
;
2544 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2545 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2546 sysbg
.Green() == m_backgroundColour
.Green() &&
2547 sysbg
.Blue() == m_backgroundColour
.Blue())
2549 m_backgroundColour
= wxNullColour
;
2551 m_backgroundColour
= sysbg
;
2559 void wxWindow::SetWindowStyleFlag( long flag
)
2561 m_windowStyle
= flag
;
2564 long wxWindow::GetWindowStyleFlag() const
2566 return m_windowStyle
;
2569 void wxWindow::CaptureMouse()
2571 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2573 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2575 GtkWidget
*connect_widget
= GetConnectWidget();
2576 gtk_grab_add( connect_widget
);
2577 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2579 (GDK_BUTTON_PRESS_MASK
|
2580 GDK_BUTTON_RELEASE_MASK
|
2581 GDK_POINTER_MOTION_MASK
),
2588 void wxWindow::ReleaseMouse()
2590 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2592 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2594 GtkWidget
*connect_widget
= GetConnectWidget();
2595 gtk_grab_remove( connect_widget
);
2596 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2597 g_capturing
= FALSE
;
2600 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2604 wxString
wxWindow::GetTitle() const
2606 return (wxString
&)m_windowName
;
2609 wxString
wxWindow::GetLabel() const
2614 void wxWindow::SetName( const wxString
&name
)
2616 m_windowName
= name
;
2619 wxString
wxWindow::GetName() const
2621 return (wxString
&)m_windowName
;
2624 bool wxWindow::IsShown() const
2629 bool wxWindow::IsRetained()
2634 wxWindow
*wxWindow::FindWindow( long id
)
2636 if (id
== m_windowId
) return this;
2637 wxNode
*node
= m_children
.First();
2640 wxWindow
*child
= (wxWindow
*)node
->Data();
2641 wxWindow
*res
= child
->FindWindow( id
);
2642 if (res
) return res
;
2643 node
= node
->Next();
2645 return (wxWindow
*) NULL
;
2648 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2650 if (name
== m_windowName
) return this;
2651 wxNode
*node
= m_children
.First();
2654 wxWindow
*child
= (wxWindow
*)node
->Data();
2655 wxWindow
*res
= child
->FindWindow( name
);
2656 if (res
) return res
;
2657 node
= node
->Next();
2659 return (wxWindow
*) NULL
;
2662 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2663 int range
, bool refresh
)
2665 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2667 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2669 m_hasScrolling
= TRUE
;
2671 if (orient
== wxHORIZONTAL
)
2673 float fpos
= (float)pos
;
2674 float frange
= (float)range
;
2675 float fthumb
= (float)thumbVisible
;
2676 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2677 if (fpos
< 0.0) fpos
= 0.0;
2679 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2680 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2682 SetScrollPos( orient
, pos
, refresh
);
2686 m_oldHorizontalPos
= fpos
;
2688 m_hAdjust
->lower
= 0.0;
2689 m_hAdjust
->upper
= frange
;
2690 m_hAdjust
->value
= fpos
;
2691 m_hAdjust
->step_increment
= 1.0;
2692 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2693 m_hAdjust
->page_size
= fthumb
;
2697 float fpos
= (float)pos
;
2698 float frange
= (float)range
;
2699 float fthumb
= (float)thumbVisible
;
2700 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2701 if (fpos
< 0.0) fpos
= 0.0;
2703 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2704 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2706 SetScrollPos( orient
, pos
, refresh
);
2710 m_oldVerticalPos
= fpos
;
2712 m_vAdjust
->lower
= 0.0;
2713 m_vAdjust
->upper
= frange
;
2714 m_vAdjust
->value
= fpos
;
2715 m_vAdjust
->step_increment
= 1.0;
2716 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2717 m_vAdjust
->page_size
= fthumb
;
2720 if (m_wxwindow
->window
)
2722 if (orient
== wxHORIZONTAL
)
2723 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2725 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2727 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2731 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2733 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2735 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2737 if (orient
== wxHORIZONTAL
)
2739 float fpos
= (float)pos
;
2740 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2741 if (fpos
< 0.0) fpos
= 0.0;
2742 m_oldHorizontalPos
= fpos
;
2744 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2745 m_hAdjust
->value
= fpos
;
2749 float fpos
= (float)pos
;
2750 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2751 if (fpos
< 0.0) fpos
= 0.0;
2752 m_oldVerticalPos
= fpos
;
2754 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2755 m_vAdjust
->value
= fpos
;
2760 if (m_wxwindow
->window
)
2762 if (orient
== wxHORIZONTAL
)
2763 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2765 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2770 int wxWindow::GetScrollThumb( int orient
) const
2772 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2774 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2776 if (orient
== wxHORIZONTAL
)
2777 return (int)(m_hAdjust
->page_size
+0.5);
2779 return (int)(m_vAdjust
->page_size
+0.5);
2782 int wxWindow::GetScrollPos( int orient
) const
2784 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2786 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2788 if (orient
== wxHORIZONTAL
)
2789 return (int)(m_hAdjust
->value
+0.5);
2791 return (int)(m_vAdjust
->value
+0.5);
2794 int wxWindow::GetScrollRange( int orient
) const
2796 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2798 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2800 if (orient
== wxHORIZONTAL
)
2801 return (int)(m_hAdjust
->upper
+0.5);
2803 return (int)(m_vAdjust
->upper
+0.5);
2806 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2808 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2810 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2814 GetClientSize( &cw
, &ch
);
2816 int w
= cw
- abs(dx
);
2817 int h
= ch
- abs(dy
);
2818 if ((h
< 0) || (w
< 0))
2825 if (dx
< 0) s_x
= -dx
;
2826 if (dy
< 0) s_y
= -dy
;
2829 if (dx
> 0) d_x
= dx
;
2830 if (dy
> 0) d_y
= dy
;
2834 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2835 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2838 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2839 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2842 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2843 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2844 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2845 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2847 Refresh( TRUE
, &rect
);
2850 //-------------------------------------------------------------------------------------
2852 //-------------------------------------------------------------------------------------
2854 wxLayoutConstraints
*wxWindow::GetConstraints() const
2856 return m_constraints
;
2859 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2863 UnsetConstraints(m_constraints
);
2864 delete m_constraints
;
2866 m_constraints
= constraints
;
2869 // Make sure other windows know they're part of a 'meaningful relationship'
2870 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2871 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2872 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2873 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2874 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2875 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2876 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2877 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2878 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2879 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2880 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2881 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2882 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2883 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2884 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2885 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2891 void wxWindow::SetAutoLayout( bool autoLayout
)
2893 m_autoLayout
= autoLayout
;
2896 bool wxWindow::GetAutoLayout() const
2898 return m_autoLayout
;
2901 wxSizer
*wxWindow::GetSizer() const
2903 return m_windowSizer
;
2906 void wxWindow::SetSizerParent( wxWindow
*win
)
2908 m_sizerParent
= win
;
2911 wxWindow
*wxWindow::GetSizerParent() const
2913 return m_sizerParent
;
2916 // This removes any dangling pointers to this window
2917 // in other windows' constraintsInvolvedIn lists.
2918 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2922 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2923 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2924 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2925 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2926 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2927 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2928 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2929 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2930 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2931 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2932 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2933 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2934 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2935 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2936 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2937 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2941 // Back-pointer to other windows we're involved with, so if we delete
2942 // this window, we must delete any constraints we're involved with.
2943 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2945 if (!m_constraintsInvolvedIn
)
2946 m_constraintsInvolvedIn
= new wxList
;
2947 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2948 m_constraintsInvolvedIn
->Append(otherWin
);
2951 // REMOVE back-pointer to other windows we're involved with.
2952 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2954 if (m_constraintsInvolvedIn
)
2955 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2958 // Reset any constraints that mention this window
2959 void wxWindow::DeleteRelatedConstraints()
2961 if (m_constraintsInvolvedIn
)
2963 wxNode
*node
= m_constraintsInvolvedIn
->First();
2966 wxWindow
*win
= (wxWindow
*)node
->Data();
2967 wxNode
*next
= node
->Next();
2968 wxLayoutConstraints
*constr
= win
->GetConstraints();
2970 // Reset any constraints involving this window
2973 constr
->left
.ResetIfWin((wxWindow
*)this);
2974 constr
->top
.ResetIfWin((wxWindow
*)this);
2975 constr
->right
.ResetIfWin((wxWindow
*)this);
2976 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2977 constr
->width
.ResetIfWin((wxWindow
*)this);
2978 constr
->height
.ResetIfWin((wxWindow
*)this);
2979 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2980 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2985 delete m_constraintsInvolvedIn
;
2986 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2990 void wxWindow::SetSizer(wxSizer
*sizer
)
2992 m_windowSizer
= sizer
;
2994 sizer
->SetSizerParent((wxWindow
*)this);
3001 bool wxWindow::Layout()
3003 if (GetConstraints())
3006 GetClientSize(&w
, &h
);
3007 GetConstraints()->width
.SetValue(w
);
3008 GetConstraints()->height
.SetValue(h
);
3011 // If top level (one sizer), evaluate the sizer's constraints.
3015 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3016 GetSizer()->LayoutPhase1(&noChanges
);
3017 GetSizer()->LayoutPhase2(&noChanges
);
3018 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3023 // Otherwise, evaluate child constraints
3024 ResetConstraints(); // Mark all constraints as unevaluated
3025 DoPhase(1); // Just one phase need if no sizers involved
3027 SetConstraintSizes(); // Recursively set the real window sizes
3033 // Do a phase of evaluating constraints:
3034 // the default behaviour. wxSizers may do a similar
3035 // thing, but also impose their own 'constraints'
3036 // and order the evaluation differently.
3037 bool wxWindow::LayoutPhase1(int *noChanges
)
3039 wxLayoutConstraints
*constr
= GetConstraints();
3042 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3048 bool wxWindow::LayoutPhase2(int *noChanges
)
3058 // Do a phase of evaluating child constraints
3059 bool wxWindow::DoPhase(int phase
)
3061 int noIterations
= 0;
3062 int maxIterations
= 500;
3066 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3070 wxNode
*node
= m_children
.First();
3073 wxWindow
*child
= (wxWindow
*)node
->Data();
3074 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3076 wxLayoutConstraints
*constr
= child
->GetConstraints();
3079 if (succeeded
.Member(child
))
3084 int tempNoChanges
= 0;
3085 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3086 noChanges
+= tempNoChanges
;
3089 succeeded
.Append(child
);
3094 node
= node
->Next();
3101 void wxWindow::ResetConstraints()
3103 wxLayoutConstraints
*constr
= GetConstraints();
3106 constr
->left
.SetDone(FALSE
);
3107 constr
->top
.SetDone(FALSE
);
3108 constr
->right
.SetDone(FALSE
);
3109 constr
->bottom
.SetDone(FALSE
);
3110 constr
->width
.SetDone(FALSE
);
3111 constr
->height
.SetDone(FALSE
);
3112 constr
->centreX
.SetDone(FALSE
);
3113 constr
->centreY
.SetDone(FALSE
);
3115 wxNode
*node
= m_children
.First();
3118 wxWindow
*win
= (wxWindow
*)node
->Data();
3119 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3120 win
->ResetConstraints();
3121 node
= node
->Next();
3125 // Need to distinguish between setting the 'fake' size for
3126 // windows and sizers, and setting the real values.
3127 void wxWindow::SetConstraintSizes(bool recurse
)
3129 wxLayoutConstraints
*constr
= GetConstraints();
3130 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3131 constr
->width
.GetDone() && constr
->height
.GetDone())
3133 int x
= constr
->left
.GetValue();
3134 int y
= constr
->top
.GetValue();
3135 int w
= constr
->width
.GetValue();
3136 int h
= constr
->height
.GetValue();
3138 // If we don't want to resize this window, just move it...
3139 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3140 (constr
->height
.GetRelationship() != wxAsIs
))
3142 // Calls Layout() recursively. AAAGH. How can we stop that.
3143 // Simply take Layout() out of non-top level OnSizes.
3144 SizerSetSize(x
, y
, w
, h
);
3153 char *windowClass
= this->GetClassInfo()->GetClassName();
3156 if (GetName() == "")
3157 winName
= "unnamed";
3159 winName
= GetName();
3160 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3161 (const char *)windowClass
,
3162 (const char *)winName
);
3163 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3164 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3165 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3166 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3167 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3172 wxNode
*node
= m_children
.First();
3175 wxWindow
*win
= (wxWindow
*)node
->Data();
3176 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3177 win
->SetConstraintSizes();
3178 node
= node
->Next();
3183 // This assumes that all sizers are 'on' the same
3184 // window, i.e. the parent of this window.
3185 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3187 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3188 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3192 m_sizerParent
->GetPosition(&xp
, &yp
);
3193 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3198 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3202 TransformSizerToActual(&xx
, &yy
);
3203 SetSize(xx
, yy
, w
, h
);
3206 void wxWindow::SizerMove(int x
, int y
)
3210 TransformSizerToActual(&xx
, &yy
);
3214 // Only set the size/position of the constraint (if any)
3215 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3217 wxLayoutConstraints
*constr
= GetConstraints();
3222 constr
->left
.SetValue(x
);
3223 constr
->left
.SetDone(TRUE
);
3227 constr
->top
.SetValue(y
);
3228 constr
->top
.SetDone(TRUE
);
3232 constr
->width
.SetValue(w
);
3233 constr
->width
.SetDone(TRUE
);
3237 constr
->height
.SetValue(h
);
3238 constr
->height
.SetDone(TRUE
);
3243 void wxWindow::MoveConstraint(int x
, int y
)
3245 wxLayoutConstraints
*constr
= GetConstraints();
3250 constr
->left
.SetValue(x
);
3251 constr
->left
.SetDone(TRUE
);
3255 constr
->top
.SetValue(y
);
3256 constr
->top
.SetDone(TRUE
);
3261 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3263 wxLayoutConstraints
*constr
= GetConstraints();
3266 *w
= constr
->width
.GetValue();
3267 *h
= constr
->height
.GetValue();
3273 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3275 wxLayoutConstraints
*constr
= GetConstraints();
3278 *w
= constr
->width
.GetValue();
3279 *h
= constr
->height
.GetValue();
3282 GetClientSize(w
, h
);
3285 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3287 wxLayoutConstraints
*constr
= GetConstraints();
3290 *x
= constr
->left
.GetValue();
3291 *y
= constr
->top
.GetValue();
3297 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )