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 #if 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 wxWindow
* wxGetActiveWindow()
1115 return g_focusWindow
;
1118 //-----------------------------------------------------------------------------
1120 //-----------------------------------------------------------------------------
1122 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1124 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1125 EVT_SIZE(wxWindow::OnSize
)
1126 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1127 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1128 EVT_IDLE(wxWindow::OnIdle
)
1131 wxWindow::wxWindow()
1133 m_widget
= (GtkWidget
*) NULL
;
1134 m_wxwindow
= (GtkWidget
*) NULL
;
1135 m_parent
= (wxWindow
*) NULL
;
1136 m_children
.DeleteContents( FALSE
);
1149 m_eventHandler
= this;
1150 m_windowValidator
= (wxValidator
*) NULL
;
1154 m_cursor
= (wxCursor
*) NULL
;
1155 m_font
= *wxSWISS_FONT
;
1157 m_windowName
= "noname";
1159 m_constraints
= (wxLayoutConstraints
*) NULL
;
1160 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1161 m_windowSizer
= (wxSizer
*) NULL
;
1162 m_sizerParent
= (wxWindow
*) NULL
;
1163 m_autoLayout
= FALSE
;
1167 m_needParent
= TRUE
;
1169 m_hasScrolling
= FALSE
;
1170 m_isScrolling
= FALSE
;
1171 m_hAdjust
= (GtkAdjustment
*) NULL
;
1172 m_vAdjust
= (GtkAdjustment
*) NULL
;
1173 m_oldHorizontalPos
= 0.0;
1174 m_oldVerticalPos
= 0.0;
1179 #if wxUSE_DRAG_AND_DROP
1180 m_dropTarget
= (wxDropTarget
*) NULL
;
1183 m_scrollGC
= (GdkGC
*) NULL
;
1184 m_widgetStyle
= (GtkStyle
*) NULL
;
1186 m_insertCallback
= wxInsertChildInWindow
;
1188 m_clientObject
= (wxClientData
*) NULL
;
1189 m_clientData
= NULL
;
1191 m_isStaticBox
= FALSE
;
1192 m_acceptsFocus
= FALSE
;
1195 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1196 const wxPoint
&pos
, const wxSize
&size
,
1197 long style
, const wxString
&name
)
1199 m_insertCallback
= wxInsertChildInWindow
;
1200 Create( parent
, id
, pos
, size
, style
, name
);
1203 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1204 const wxPoint
&pos
, const wxSize
&size
,
1205 long style
, const wxString
&name
)
1209 m_needParent
= TRUE
;
1211 PreCreation( parent
, id
, pos
, size
, style
, name
);
1213 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1214 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1217 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1220 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1223 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1224 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1227 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1228 scroll_class
->scrollbar_spacing
= 0;
1230 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1232 m_oldHorizontalPos
= 0.0;
1233 m_oldVerticalPos
= 0.0;
1235 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1236 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1238 m_wxwindow
= gtk_myfixed_new();
1241 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1244 #ifdef NEW_GTK_SCROLL_CODE
1245 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1246 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1248 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1249 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1253 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1256 if (m_windowStyle
& wxRAISED_BORDER
)
1258 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1260 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1262 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1266 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1269 if ((m_windowStyle
& wxTAB_TRAVERSAL
) != 0)
1271 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1272 m_acceptsFocus
= FALSE
;
1276 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1277 m_acceptsFocus
= TRUE
;
1280 // shut the viewport up
1281 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1282 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1284 // I _really_ don't want scrollbars in the beginning
1285 m_vAdjust
->lower
= 0.0;
1286 m_vAdjust
->upper
= 1.0;
1287 m_vAdjust
->value
= 0.0;
1288 m_vAdjust
->step_increment
= 1.0;
1289 m_vAdjust
->page_increment
= 1.0;
1290 m_vAdjust
->page_size
= 5.0;
1291 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1292 m_hAdjust
->lower
= 0.0;
1293 m_hAdjust
->upper
= 1.0;
1294 m_hAdjust
->value
= 0.0;
1295 m_hAdjust
->step_increment
= 1.0;
1296 m_hAdjust
->page_increment
= 1.0;
1297 m_hAdjust
->page_size
= 5.0;
1298 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1300 // these handlers block mouse events to any window during scrolling
1301 // such as motion events and prevent GTK and wxWindows from fighting
1302 // over where the slider should be
1304 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1305 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1307 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1308 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1310 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1311 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1313 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1314 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1316 // these handers het notified when screen updates are required either when
1317 // scrolling or when the window size (and therefore scrollbar configuration)
1320 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1321 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1322 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1323 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1325 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1326 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1327 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1328 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1330 gtk_widget_show( m_wxwindow
);
1332 if (m_parent
) m_parent
->AddChild( this );
1334 (m_parent
->m_insertCallback
)( m_parent
, this );
1343 wxWindow::~wxWindow()
1347 #if wxUSE_DRAG_AND_DROP
1348 if (m_dropTarget
) delete m_dropTarget
;
1351 if (m_parent
) m_parent
->RemoveChild( this );
1352 if (m_widget
) Show( FALSE
);
1356 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1358 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1360 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1362 if (m_widget
) gtk_widget_destroy( m_widget
);
1364 if (m_cursor
) delete m_cursor
;
1366 DeleteRelatedConstraints();
1369 // This removes any dangling pointers to this window
1370 // in other windows' constraintsInvolvedIn lists.
1371 UnsetConstraints(m_constraints
);
1372 delete m_constraints
;
1373 m_constraints
= (wxLayoutConstraints
*) NULL
;
1377 delete m_windowSizer
;
1378 m_windowSizer
= (wxSizer
*) NULL
;
1380 // If this is a child of a sizer, remove self from parent
1381 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1383 // Just in case the window has been Closed, but
1384 // we're then deleting immediately: don't leave
1385 // dangling pointers.
1386 wxPendingDelete
.DeleteObject(this);
1388 // Just in case we've loaded a top-level window via
1389 // wxWindow::LoadNativeDialog but we weren't a dialog
1391 wxTopLevelWindows
.DeleteObject(this);
1393 if (m_windowValidator
) delete m_windowValidator
;
1395 if (m_clientObject
) delete m_clientObject
;
1398 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1399 const wxPoint
&pos
, const wxSize
&size
,
1400 long style
, const wxString
&name
)
1402 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1404 m_widget
= (GtkWidget
*) NULL
;
1405 m_wxwindow
= (GtkWidget
*) NULL
;
1408 m_children
.DeleteContents( FALSE
);
1411 if (m_width
== -1) m_width
= 20;
1413 if (m_height
== -1) m_height
= 20;
1418 if (!m_needParent
) // some reasonable defaults
1422 m_x
= (gdk_screen_width () - m_width
) / 2;
1423 if (m_x
< 10) m_x
= 10;
1427 m_y
= (gdk_screen_height () - m_height
) / 2;
1428 if (m_y
< 10) m_y
= 10;
1439 m_eventHandler
= this;
1441 m_windowId
= id
== -1 ? wxNewId() : id
;
1445 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1446 m_font
= *wxSWISS_FONT
;
1447 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1448 m_foregroundColour
= *wxBLACK
;
1449 m_windowStyle
= style
;
1450 m_windowName
= name
;
1452 m_constraints
= (wxLayoutConstraints
*) NULL
;
1453 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1454 m_windowSizer
= (wxSizer
*) NULL
;
1455 m_sizerParent
= (wxWindow
*) NULL
;
1456 m_autoLayout
= FALSE
;
1458 m_hasScrolling
= FALSE
;
1459 m_isScrolling
= FALSE
;
1460 m_hAdjust
= (GtkAdjustment
*) NULL
;
1461 m_vAdjust
= (GtkAdjustment
*) NULL
;
1462 m_oldHorizontalPos
= 0.0;
1463 m_oldVerticalPos
= 0.0;
1468 #if wxUSE_DRAG_AND_DROP
1469 m_dropTarget
= (wxDropTarget
*) NULL
;
1472 m_windowValidator
= (wxValidator
*) NULL
;
1473 m_scrollGC
= (GdkGC
*) NULL
;
1474 m_widgetStyle
= (GtkStyle
*) NULL
;
1476 m_clientObject
= (wxClientData
*)NULL
;
1477 m_clientData
= NULL
;
1479 m_isStaticBox
= FALSE
;
1482 void wxWindow::PostCreation()
1486 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1487 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1489 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1490 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1493 ConnectWidget( GetConnectWidget() );
1495 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1497 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1499 SetCursor( *wxSTANDARD_CURSOR
);
1504 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1506 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1507 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1509 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1510 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1512 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1513 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1515 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1516 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1518 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1519 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1521 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1522 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1524 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1525 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1527 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1528 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1531 bool wxWindow::HasVMT()
1536 bool wxWindow::Close( bool force
)
1538 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1540 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1541 event
.SetEventObject(this);
1542 event
.SetForce(force
);
1544 return GetEventHandler()->ProcessEvent(event
);
1547 bool wxWindow::Destroy()
1549 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1556 bool wxWindow::DestroyChildren()
1559 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1562 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1565 if (m_children
.Member(child
)) delete node
;
1571 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1573 // are we to set fonts here ?
1576 wxPoint
wxWindow::GetClientAreaOrigin() const
1578 return wxPoint(0,0);
1581 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1583 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1585 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1591 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1593 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1594 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1596 if (m_resizing
) return; // I don't like recursions
1599 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1601 // don't set the size for children of wxNotebook, just take the values.
1609 int old_width
= m_width
;
1610 int old_height
= m_height
;
1612 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1614 if (x
!= -1) m_x
= x
;
1615 if (y
!= -1) m_y
= y
;
1616 if (width
!= -1) m_width
= width
;
1617 if (height
!= -1) m_height
= height
;
1627 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1629 if (width
== -1) m_width
= 80;
1632 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1634 if (height
== -1) m_height
= 26;
1637 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1638 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1639 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1640 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1642 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1643 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1645 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1646 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1651 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1652 event
.SetEventObject( this );
1653 GetEventHandler()->ProcessEvent( event
);
1658 void wxWindow::SetSize( int width
, int height
)
1660 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1663 void wxWindow::Move( int x
, int y
)
1665 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1668 void wxWindow::GetSize( int *width
, int *height
) const
1670 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1672 if (width
) (*width
) = m_width
;
1673 if (height
) (*height
) = m_height
;
1676 void wxWindow::SetClientSize( int width
, int height
)
1678 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1682 SetSize( width
, height
);
1689 if (!m_hasScrolling
)
1691 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1693 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1694 (m_windowStyle
& wxSUNKEN_BORDER
))
1696 dw
+= 2 * window_class
->xthickness
;
1697 dh
+= 2 * window_class
->ythickness
;
1702 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1703 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1705 #ifdef NEW_GTK_SCROLL_CODE
1706 GtkWidget
*viewport
= scroll_window
->child
;
1708 GtkWidget
*viewport
= scroll_window
->viewport
;
1711 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1713 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1714 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1716 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1717 (m_windowStyle
& wxSUNKEN_BORDER
))
1719 dw
+= 2 * viewport_class
->xthickness
;
1720 dh
+= 2 * viewport_class
->ythickness
;
1723 if (scroll_window
->vscrollbar_visible
)
1725 dw
+= vscrollbar
->allocation
.width
;
1726 dw
+= scroll_class
->scrollbar_spacing
;
1729 if (scroll_window
->hscrollbar_visible
)
1731 dh
+= hscrollbar
->allocation
.height
;
1732 dw
+= scroll_class
->scrollbar_spacing
;
1736 SetSize( width
+dw
, height
+dh
);
1740 void wxWindow::GetClientSize( int *width
, int *height
) const
1742 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1746 if (width
) (*width
) = m_width
;
1747 if (height
) (*height
) = m_height
;
1754 if (!m_hasScrolling
)
1756 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1758 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1759 (m_windowStyle
& wxSUNKEN_BORDER
))
1761 dw
+= 2 * window_class
->xthickness
;
1762 dh
+= 2 * window_class
->ythickness
;
1767 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1768 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1770 #ifdef NEW_GTK_SCROLL_CODE
1771 GtkWidget
*viewport
= scroll_window
->child
;
1773 GtkWidget
*viewport
= scroll_window
->viewport
;
1776 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1778 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1779 (m_windowStyle
& wxSUNKEN_BORDER
))
1781 dw
+= 2 * viewport_class
->xthickness
;
1782 dh
+= 2 * viewport_class
->ythickness
;
1785 if (scroll_window
->vscrollbar_visible
)
1787 // dw += vscrollbar->allocation.width;
1788 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1789 dw
+= scroll_class
->scrollbar_spacing
;
1792 if (scroll_window
->hscrollbar_visible
)
1794 // dh += hscrollbar->allocation.height;
1796 dh
+= scroll_class
->scrollbar_spacing
;
1800 if (width
) (*width
) = m_width
- dw
;
1801 if (height
) (*height
) = m_height
- dh
;
1805 void wxWindow::GetPosition( int *x
, int *y
) const
1807 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1813 void wxWindow::ClientToScreen( int *x
, int *y
)
1815 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1817 GdkWindow
*source
= (GdkWindow
*) NULL
;
1819 source
= m_wxwindow
->window
;
1821 source
= m_widget
->window
;
1825 gdk_window_get_origin( source
, &org_x
, &org_y
);
1829 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1831 org_x
+= m_widget
->allocation
.x
;
1832 org_y
+= m_widget
->allocation
.y
;
1836 wxPoint
pt(GetClientAreaOrigin());
1844 void wxWindow::ScreenToClient( int *x
, int *y
)
1846 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1848 GdkWindow
*source
= (GdkWindow
*) NULL
;
1850 source
= m_wxwindow
->window
;
1852 source
= m_widget
->window
;
1856 gdk_window_get_origin( source
, &org_x
, &org_y
);
1860 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1862 org_x
+= m_widget
->allocation
.x
;
1863 org_y
+= m_widget
->allocation
.y
;
1867 wxPoint
pt(GetClientAreaOrigin());
1875 void wxWindow::Centre( int direction
)
1877 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1886 m_parent
->GetSize( &p_w
, &p_h
);
1887 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
1888 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
1892 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
1893 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
1899 void wxWindow::Fit()
1901 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1905 wxNode
*node
= m_children
.First();
1908 wxWindow
*win
= (wxWindow
*)node
->Data();
1910 win
->GetPosition(&wx
, &wy
);
1911 win
->GetSize(&ww
, &wh
);
1912 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
1913 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
1915 node
= node
->Next();
1918 SetClientSize(maxX
+ 7, maxY
+ 14);
1921 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1923 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1931 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1933 // if (GetAutoLayout()) Layout();
1936 bool wxWindow::Show( bool show
)
1938 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
1941 gtk_widget_show( m_widget
);
1943 gtk_widget_hide( m_widget
);
1950 void wxWindow::Enable( bool enable
)
1952 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1954 m_isEnabled
= enable
;
1956 gtk_widget_set_sensitive( m_widget
, enable
);
1957 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1960 int wxWindow::GetCharHeight() const
1962 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
1964 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
1966 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1968 return font
->ascent
+ font
->descent
;
1971 int wxWindow::GetCharWidth() const
1973 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
1975 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
1977 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1979 return gdk_string_width( font
, "H" );
1982 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1983 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1985 wxFont fontToUse
= m_font
;
1986 if (theFont
) fontToUse
= *theFont
;
1988 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
1990 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1991 if (x
) (*x
) = gdk_string_width( font
, string
);
1992 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1993 if (descent
) (*descent
) = font
->descent
;
1994 if (externalLeading
) (*externalLeading
) = 0; // ??
1997 void wxWindow::MakeModal( bool modal
)
2001 // Disable all other windows
2002 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2004 wxNode
*node
= wxTopLevelWindows
.First();
2007 wxWindow
*win
= (wxWindow
*)node
->Data();
2008 if (win
!= this) win
->Enable(!modal
);
2010 node
= node
->Next();
2015 void wxWindow::SetFocus()
2017 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2019 GtkWidget
*connect_widget
= GetConnectWidget();
2022 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2024 gtk_widget_grab_focus (connect_widget
);
2026 else if (GTK_IS_CONTAINER(connect_widget
))
2028 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2036 wxWindow
*wxWindow::FindFocus()
2038 return g_focusWindow
;
2041 bool wxWindow::AcceptsFocus() const
2043 return IsEnabled() && IsShown() && m_acceptsFocus
;
2046 bool wxWindow::OnClose()
2051 void wxWindow::AddChild( wxWindow
*child
)
2053 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2054 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2056 m_children
.Append( child
);
2059 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2061 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2063 wxWindow
*oldParent
= GetParent();
2065 if (oldParent
) oldParent
->RemoveChild( this );
2067 gtk_widget_unparent( m_widget
);
2071 newParent
->AddChild( this );
2072 (newParent
->m_insertCallback
)( newParent
, this );
2078 void wxWindow::RemoveChild( wxWindow
*child
)
2080 m_children
.DeleteObject( child
);
2081 child
->m_parent
= (wxWindow
*) NULL
;
2084 void wxWindow::SetReturnCode( int retCode
)
2086 m_retCode
= retCode
;
2089 int wxWindow::GetReturnCode()
2094 void wxWindow::Raise()
2096 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2098 if (m_widget
) gdk_window_raise( m_widget
->window
);
2101 void wxWindow::Lower()
2103 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2105 if (m_widget
) gdk_window_lower( m_widget
->window
);
2108 wxEvtHandler
*wxWindow::GetEventHandler() const
2110 return m_eventHandler
;
2113 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2115 m_eventHandler
= handler
;
2118 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2120 handler
->SetNextHandler(GetEventHandler());
2121 SetEventHandler(handler
);
2124 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2126 if (GetEventHandler())
2128 wxEvtHandler
*handlerA
= GetEventHandler();
2129 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2130 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2131 SetEventHandler(handlerB
);
2135 return (wxEvtHandler
*) NULL
;
2141 return (wxEvtHandler
*) NULL
;
2144 wxValidator
*wxWindow::GetValidator()
2146 return m_windowValidator
;
2149 void wxWindow::SetValidator( const wxValidator
& validator
)
2151 if (m_windowValidator
) delete m_windowValidator
;
2152 m_windowValidator
= validator
.Clone();
2153 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2156 void wxWindow::SetClientObject( wxClientData
*data
)
2158 if (m_clientObject
) delete m_clientObject
;
2159 m_clientObject
= data
;
2162 wxClientData
*wxWindow::GetClientObject()
2164 return m_clientObject
;
2167 void wxWindow::SetClientData( void *data
)
2169 m_clientData
= data
;
2172 void *wxWindow::GetClientData()
2174 return m_clientData
;
2177 bool wxWindow::IsBeingDeleted()
2182 void wxWindow::SetId( wxWindowID id
)
2187 wxWindowID
wxWindow::GetId() const
2192 void wxWindow::SetCursor( const wxCursor
&cursor
)
2194 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2198 if (cursor
== *m_cursor
) return;
2203 *m_cursor
= *wxSTANDARD_CURSOR
;
2206 if ((m_widget
) && (m_widget
->window
))
2207 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2209 if ((m_wxwindow
) && (m_wxwindow
->window
))
2210 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2213 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2218 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2220 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2222 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2226 gdk_window_clear_area( m_wxwindow
->window
,
2240 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2242 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2246 GdkRectangle gdk_rect
;
2247 gdk_rect
.x
= rect
->x
;
2248 gdk_rect
.y
= rect
->y
;
2249 gdk_rect
.width
= rect
->width
;
2250 gdk_rect
.height
= rect
->height
;
2253 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2255 gtk_widget_draw( m_widget
, &gdk_rect
);
2259 wxRegion
wxWindow::GetUpdateRegion() const
2261 return m_updateRegion
;
2264 bool wxWindow::IsExposed( int x
, int y
) const
2266 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2269 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2271 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2274 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2276 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2279 bool wxWindow::IsExposed( const wxRect
& rect
) const
2281 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2284 void wxWindow::Clear()
2286 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2288 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2291 wxColour
wxWindow::GetBackgroundColour() const
2293 return m_backgroundColour
;
2296 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2298 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2300 if (m_backgroundColour
== colour
) return;
2302 m_backgroundColour
= colour
;
2303 if (!m_backgroundColour
.Ok()) return;
2307 GdkWindow
*window
= m_wxwindow
->window
;
2308 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2309 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2310 gdk_window_clear( window
);
2313 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2314 if (sysbg
.Red() == colour
.Red() &&
2315 sysbg
.Green() == colour
.Green() &&
2316 sysbg
.Blue() == colour
.Blue())
2318 m_backgroundColour
= wxNullColour
;
2320 m_backgroundColour
= sysbg
;
2328 wxColour
wxWindow::GetForegroundColour() const
2330 return m_foregroundColour
;
2333 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2335 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2337 if (m_foregroundColour
== colour
) return;
2339 m_foregroundColour
= colour
;
2340 if (!m_foregroundColour
.Ok()) return;
2342 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2343 if (sysbg
.Red() == colour
.Red() &&
2344 sysbg
.Green() == colour
.Green() &&
2345 sysbg
.Blue() == colour
.Blue())
2347 m_backgroundColour
= wxNullColour
;
2349 m_backgroundColour
= sysbg
;
2357 GtkStyle
*wxWindow::GetWidgetStyle()
2359 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2363 gtk_widget_get_style( m_widget
) );
2365 return m_widgetStyle
;
2368 void wxWindow::SetWidgetStyle()
2370 GtkStyle
*style
= GetWidgetStyle();
2372 gdk_font_unref( style
->font
);
2373 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2375 if (m_foregroundColour
.Ok())
2377 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2378 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2379 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2380 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2383 if (m_backgroundColour
.Ok())
2385 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2386 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2387 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2388 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2389 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2390 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2391 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2392 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2393 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2397 void wxWindow::ApplyWidgetStyle()
2401 bool wxWindow::Validate()
2403 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2405 wxNode
*node
= m_children
.First();
2408 wxWindow
*child
= (wxWindow
*)node
->Data();
2409 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2413 node
= node
->Next();
2418 bool wxWindow::TransferDataToWindow()
2420 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2422 wxNode
*node
= m_children
.First();
2425 wxWindow
*child
= (wxWindow
*)node
->Data();
2426 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2427 !child
->GetValidator()->TransferToWindow() )
2429 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2432 node
= node
->Next();
2437 bool wxWindow::TransferDataFromWindow()
2439 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2441 wxNode
*node
= m_children
.First();
2444 wxWindow
*child
= (wxWindow
*)node
->Data();
2445 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2449 node
= node
->Next();
2454 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2456 m_acceleratorTable
= accel
;
2459 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2461 TransferDataToWindow();
2464 void wxWindow::InitDialog()
2466 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2468 wxInitDialogEvent
event(GetId());
2469 event
.SetEventObject( this );
2470 GetEventHandler()->ProcessEvent(event
);
2473 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2475 menu
->SetInvokingWindow( win
);
2476 wxNode
*node
= menu
->m_items
.First();
2479 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2480 if (menuitem
->IsSubMenu())
2482 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2484 node
= node
->Next();
2488 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2490 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2492 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2494 SetInvokingWindow( menu
, this );
2496 GTK_MENU(menu
->m_menu
),
2497 (GtkWidget
*)NULL
, // parent menu shell
2498 (GtkWidget
*)NULL
, // parent menu item
2499 (GtkMenuPositionFunc
)NULL
,
2500 NULL
, // client data
2501 0, // button used to activate it
2502 0//gs_timeLastClick // the time of activation
2507 #if wxUSE_DRAG_AND_DROP
2509 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2511 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2513 GtkWidget
*dnd_widget
= GetConnectWidget();
2515 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2517 if (m_dropTarget
) delete m_dropTarget
;
2518 m_dropTarget
= dropTarget
;
2520 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2523 wxDropTarget
*wxWindow::GetDropTarget() const
2525 return m_dropTarget
;
2530 GtkWidget
* wxWindow::GetConnectWidget()
2532 GtkWidget
*connect_widget
= m_widget
;
2533 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2535 return connect_widget
;
2538 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2540 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2541 return (window
== m_widget
->window
);
2544 void wxWindow::SetFont( const wxFont
&font
)
2546 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2548 if (((wxFont
*)&font
)->Ok())
2551 m_font
= *wxSWISS_FONT
;
2553 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2554 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2555 sysbg
.Green() == m_backgroundColour
.Green() &&
2556 sysbg
.Blue() == m_backgroundColour
.Blue())
2558 m_backgroundColour
= wxNullColour
;
2560 m_backgroundColour
= sysbg
;
2568 void wxWindow::SetWindowStyleFlag( long flag
)
2570 m_windowStyle
= flag
;
2573 long wxWindow::GetWindowStyleFlag() const
2575 return m_windowStyle
;
2578 void wxWindow::CaptureMouse()
2580 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2582 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2584 GtkWidget
*connect_widget
= GetConnectWidget();
2585 gtk_grab_add( connect_widget
);
2586 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2588 (GDK_BUTTON_PRESS_MASK
|
2589 GDK_BUTTON_RELEASE_MASK
|
2590 GDK_POINTER_MOTION_MASK
),
2597 void wxWindow::ReleaseMouse()
2599 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2601 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2603 GtkWidget
*connect_widget
= GetConnectWidget();
2604 gtk_grab_remove( connect_widget
);
2605 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2606 g_capturing
= FALSE
;
2609 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2613 wxString
wxWindow::GetTitle() const
2615 return (wxString
&)m_windowName
;
2618 wxString
wxWindow::GetLabel() const
2623 void wxWindow::SetName( const wxString
&name
)
2625 m_windowName
= name
;
2628 wxString
wxWindow::GetName() const
2630 return (wxString
&)m_windowName
;
2633 bool wxWindow::IsShown() const
2638 bool wxWindow::IsRetained()
2643 wxWindow
*wxWindow::FindWindow( long id
)
2645 if (id
== m_windowId
) return this;
2646 wxNode
*node
= m_children
.First();
2649 wxWindow
*child
= (wxWindow
*)node
->Data();
2650 wxWindow
*res
= child
->FindWindow( id
);
2651 if (res
) return res
;
2652 node
= node
->Next();
2654 return (wxWindow
*) NULL
;
2657 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2659 if (name
== m_windowName
) return this;
2660 wxNode
*node
= m_children
.First();
2663 wxWindow
*child
= (wxWindow
*)node
->Data();
2664 wxWindow
*res
= child
->FindWindow( name
);
2665 if (res
) return res
;
2666 node
= node
->Next();
2668 return (wxWindow
*) NULL
;
2671 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2672 int range
, bool refresh
)
2674 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2676 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2678 m_hasScrolling
= TRUE
;
2680 if (orient
== wxHORIZONTAL
)
2682 float fpos
= (float)pos
;
2683 float frange
= (float)range
;
2684 float fthumb
= (float)thumbVisible
;
2685 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2686 if (fpos
< 0.0) fpos
= 0.0;
2688 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2689 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2691 SetScrollPos( orient
, pos
, refresh
);
2695 m_oldHorizontalPos
= fpos
;
2697 m_hAdjust
->lower
= 0.0;
2698 m_hAdjust
->upper
= frange
;
2699 m_hAdjust
->value
= fpos
;
2700 m_hAdjust
->step_increment
= 1.0;
2701 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2702 m_hAdjust
->page_size
= fthumb
;
2706 float fpos
= (float)pos
;
2707 float frange
= (float)range
;
2708 float fthumb
= (float)thumbVisible
;
2709 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2710 if (fpos
< 0.0) fpos
= 0.0;
2712 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2713 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2715 SetScrollPos( orient
, pos
, refresh
);
2719 m_oldVerticalPos
= fpos
;
2721 m_vAdjust
->lower
= 0.0;
2722 m_vAdjust
->upper
= frange
;
2723 m_vAdjust
->value
= fpos
;
2724 m_vAdjust
->step_increment
= 1.0;
2725 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2726 m_vAdjust
->page_size
= fthumb
;
2729 if (m_wxwindow
->window
)
2731 if (orient
== wxHORIZONTAL
)
2732 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2734 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2736 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2740 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2742 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2744 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2746 if (orient
== wxHORIZONTAL
)
2748 float fpos
= (float)pos
;
2749 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2750 if (fpos
< 0.0) fpos
= 0.0;
2751 m_oldHorizontalPos
= fpos
;
2753 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2754 m_hAdjust
->value
= fpos
;
2758 float fpos
= (float)pos
;
2759 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2760 if (fpos
< 0.0) fpos
= 0.0;
2761 m_oldVerticalPos
= fpos
;
2763 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2764 m_vAdjust
->value
= fpos
;
2769 if (m_wxwindow
->window
)
2771 if (orient
== wxHORIZONTAL
)
2772 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2774 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2779 int wxWindow::GetScrollThumb( int orient
) const
2781 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2783 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2785 if (orient
== wxHORIZONTAL
)
2786 return (int)(m_hAdjust
->page_size
+0.5);
2788 return (int)(m_vAdjust
->page_size
+0.5);
2791 int wxWindow::GetScrollPos( int orient
) const
2793 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2795 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2797 if (orient
== wxHORIZONTAL
)
2798 return (int)(m_hAdjust
->value
+0.5);
2800 return (int)(m_vAdjust
->value
+0.5);
2803 int wxWindow::GetScrollRange( int orient
) const
2805 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2807 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2809 if (orient
== wxHORIZONTAL
)
2810 return (int)(m_hAdjust
->upper
+0.5);
2812 return (int)(m_vAdjust
->upper
+0.5);
2815 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2817 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2819 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2823 GetClientSize( &cw
, &ch
);
2825 int w
= cw
- abs(dx
);
2826 int h
= ch
- abs(dy
);
2827 if ((h
< 0) || (w
< 0))
2834 if (dx
< 0) s_x
= -dx
;
2835 if (dy
< 0) s_y
= -dy
;
2838 if (dx
> 0) d_x
= dx
;
2839 if (dy
> 0) d_y
= dy
;
2843 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2844 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2847 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2848 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2851 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2852 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2853 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2854 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2856 Refresh( TRUE
, &rect
);
2859 //-------------------------------------------------------------------------------------
2861 //-------------------------------------------------------------------------------------
2863 wxLayoutConstraints
*wxWindow::GetConstraints() const
2865 return m_constraints
;
2868 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2872 UnsetConstraints(m_constraints
);
2873 delete m_constraints
;
2875 m_constraints
= constraints
;
2878 // Make sure other windows know they're part of a 'meaningful relationship'
2879 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2880 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2881 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2882 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2883 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2884 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2885 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2886 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2887 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2888 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2889 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2890 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2891 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2892 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2893 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2894 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2900 void wxWindow::SetAutoLayout( bool autoLayout
)
2902 m_autoLayout
= autoLayout
;
2905 bool wxWindow::GetAutoLayout() const
2907 return m_autoLayout
;
2910 wxSizer
*wxWindow::GetSizer() const
2912 return m_windowSizer
;
2915 void wxWindow::SetSizerParent( wxWindow
*win
)
2917 m_sizerParent
= win
;
2920 wxWindow
*wxWindow::GetSizerParent() const
2922 return m_sizerParent
;
2925 // This removes any dangling pointers to this window
2926 // in other windows' constraintsInvolvedIn lists.
2927 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2931 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2932 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2933 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2934 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2935 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2936 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2937 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2938 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2939 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2940 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2941 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2942 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2943 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2944 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2945 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2946 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2950 // Back-pointer to other windows we're involved with, so if we delete
2951 // this window, we must delete any constraints we're involved with.
2952 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2954 if (!m_constraintsInvolvedIn
)
2955 m_constraintsInvolvedIn
= new wxList
;
2956 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2957 m_constraintsInvolvedIn
->Append(otherWin
);
2960 // REMOVE back-pointer to other windows we're involved with.
2961 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2963 if (m_constraintsInvolvedIn
)
2964 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2967 // Reset any constraints that mention this window
2968 void wxWindow::DeleteRelatedConstraints()
2970 if (m_constraintsInvolvedIn
)
2972 wxNode
*node
= m_constraintsInvolvedIn
->First();
2975 wxWindow
*win
= (wxWindow
*)node
->Data();
2976 wxNode
*next
= node
->Next();
2977 wxLayoutConstraints
*constr
= win
->GetConstraints();
2979 // Reset any constraints involving this window
2982 constr
->left
.ResetIfWin((wxWindow
*)this);
2983 constr
->top
.ResetIfWin((wxWindow
*)this);
2984 constr
->right
.ResetIfWin((wxWindow
*)this);
2985 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2986 constr
->width
.ResetIfWin((wxWindow
*)this);
2987 constr
->height
.ResetIfWin((wxWindow
*)this);
2988 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2989 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2994 delete m_constraintsInvolvedIn
;
2995 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2999 void wxWindow::SetSizer(wxSizer
*sizer
)
3001 m_windowSizer
= sizer
;
3003 sizer
->SetSizerParent((wxWindow
*)this);
3010 bool wxWindow::Layout()
3012 if (GetConstraints())
3015 GetClientSize(&w
, &h
);
3016 GetConstraints()->width
.SetValue(w
);
3017 GetConstraints()->height
.SetValue(h
);
3020 // If top level (one sizer), evaluate the sizer's constraints.
3024 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3025 GetSizer()->LayoutPhase1(&noChanges
);
3026 GetSizer()->LayoutPhase2(&noChanges
);
3027 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3032 // Otherwise, evaluate child constraints
3033 ResetConstraints(); // Mark all constraints as unevaluated
3034 DoPhase(1); // Just one phase need if no sizers involved
3036 SetConstraintSizes(); // Recursively set the real window sizes
3042 // Do a phase of evaluating constraints:
3043 // the default behaviour. wxSizers may do a similar
3044 // thing, but also impose their own 'constraints'
3045 // and order the evaluation differently.
3046 bool wxWindow::LayoutPhase1(int *noChanges
)
3048 wxLayoutConstraints
*constr
= GetConstraints();
3051 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3057 bool wxWindow::LayoutPhase2(int *noChanges
)
3067 // Do a phase of evaluating child constraints
3068 bool wxWindow::DoPhase(int phase
)
3070 int noIterations
= 0;
3071 int maxIterations
= 500;
3075 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3079 wxNode
*node
= m_children
.First();
3082 wxWindow
*child
= (wxWindow
*)node
->Data();
3083 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3085 wxLayoutConstraints
*constr
= child
->GetConstraints();
3088 if (succeeded
.Member(child
))
3093 int tempNoChanges
= 0;
3094 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3095 noChanges
+= tempNoChanges
;
3098 succeeded
.Append(child
);
3103 node
= node
->Next();
3110 void wxWindow::ResetConstraints()
3112 wxLayoutConstraints
*constr
= GetConstraints();
3115 constr
->left
.SetDone(FALSE
);
3116 constr
->top
.SetDone(FALSE
);
3117 constr
->right
.SetDone(FALSE
);
3118 constr
->bottom
.SetDone(FALSE
);
3119 constr
->width
.SetDone(FALSE
);
3120 constr
->height
.SetDone(FALSE
);
3121 constr
->centreX
.SetDone(FALSE
);
3122 constr
->centreY
.SetDone(FALSE
);
3124 wxNode
*node
= m_children
.First();
3127 wxWindow
*win
= (wxWindow
*)node
->Data();
3128 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3129 win
->ResetConstraints();
3130 node
= node
->Next();
3134 // Need to distinguish between setting the 'fake' size for
3135 // windows and sizers, and setting the real values.
3136 void wxWindow::SetConstraintSizes(bool recurse
)
3138 wxLayoutConstraints
*constr
= GetConstraints();
3139 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3140 constr
->width
.GetDone() && constr
->height
.GetDone())
3142 int x
= constr
->left
.GetValue();
3143 int y
= constr
->top
.GetValue();
3144 int w
= constr
->width
.GetValue();
3145 int h
= constr
->height
.GetValue();
3147 // If we don't want to resize this window, just move it...
3148 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3149 (constr
->height
.GetRelationship() != wxAsIs
))
3151 // Calls Layout() recursively. AAAGH. How can we stop that.
3152 // Simply take Layout() out of non-top level OnSizes.
3153 SizerSetSize(x
, y
, w
, h
);
3162 char *windowClass
= this->GetClassInfo()->GetClassName();
3165 if (GetName() == "")
3166 winName
= "unnamed";
3168 winName
= GetName();
3169 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3170 (const char *)windowClass
,
3171 (const char *)winName
);
3172 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3173 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3174 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3175 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3176 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3181 wxNode
*node
= m_children
.First();
3184 wxWindow
*win
= (wxWindow
*)node
->Data();
3185 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3186 win
->SetConstraintSizes();
3187 node
= node
->Next();
3192 // This assumes that all sizers are 'on' the same
3193 // window, i.e. the parent of this window.
3194 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3196 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3197 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3201 m_sizerParent
->GetPosition(&xp
, &yp
);
3202 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3207 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3211 TransformSizerToActual(&xx
, &yy
);
3212 SetSize(xx
, yy
, w
, h
);
3215 void wxWindow::SizerMove(int x
, int y
)
3219 TransformSizerToActual(&xx
, &yy
);
3223 // Only set the size/position of the constraint (if any)
3224 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3226 wxLayoutConstraints
*constr
= GetConstraints();
3231 constr
->left
.SetValue(x
);
3232 constr
->left
.SetDone(TRUE
);
3236 constr
->top
.SetValue(y
);
3237 constr
->top
.SetDone(TRUE
);
3241 constr
->width
.SetValue(w
);
3242 constr
->width
.SetDone(TRUE
);
3246 constr
->height
.SetValue(h
);
3247 constr
->height
.SetDone(TRUE
);
3252 void wxWindow::MoveConstraint(int x
, int y
)
3254 wxLayoutConstraints
*constr
= GetConstraints();
3259 constr
->left
.SetValue(x
);
3260 constr
->left
.SetDone(TRUE
);
3264 constr
->top
.SetValue(y
);
3265 constr
->top
.SetDone(TRUE
);
3270 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3272 wxLayoutConstraints
*constr
= GetConstraints();
3275 *w
= constr
->width
.GetValue();
3276 *h
= constr
->height
.GetValue();
3282 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3284 wxLayoutConstraints
*constr
= GetConstraints();
3287 *w
= constr
->width
.GetValue();
3288 *h
= constr
->height
.GetValue();
3291 GetClientSize(w
, h
);
3294 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3296 wxLayoutConstraints
*constr
= GetConstraints();
3299 *x
= constr
->left
.GetValue();
3300 *y
= constr
->top
.GetValue();
3306 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )