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 #include "wx/dcclient.h"
27 #include "wx/statusbr.h"
29 #include "wx/settings.h"
31 #include "gdk/gdkprivate.h"
32 #include "gdk/gdkkeysyms.h"
36 //-----------------------------------------------------------------------------
37 // documentation on internals
38 //-----------------------------------------------------------------------------
41 I have been asked several times about writing some documentation about
42 the GTK port of wxWindows, especially its internal structures. Obviously,
43 you cannot understand wxGTK without knowing a little about the GTK, but
44 some more information about what the wxWindow, which is the base class
45 for all other window classes, does seems required as well.
47 What does wxWindow do? It contains the common interface for the following
48 jobs of its descendants:
50 1) Define the rudimentary behaviour common to all window classes, such as
51 resizing, intercepting user input (so as to make it possible to use these
52 events for special purposes in a derived class), window names etc.
54 2) Provide the possibility to contain and manage children, if the derived
55 class is allowed to contain children, which holds true for those window
56 classes which do not display a native GTK widget. To name them, these
57 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
58 work classes are a special case and are handled a bit differently from
59 the rest. The same holds true for the wxNotebook class.
61 3) Provide the possibility to draw into a client area of a window. This,
62 too, only holds true for classes that do not display a native GTK widget
65 4) Provide the entire mechanism for scrolling widgets. This actual inter-
66 face for this is usually in wxScrolledWindow, but the GTK implementation
69 5) A multitude of helper or extra methods for special purposes, such as
70 Drag'n'Drop, managing validators etc.
72 Normally one might expect, that one wxWindows window would always correspond
73 to one GTK widget. Under GTK, there is no such allround widget that has all
74 the functionality. Moreover, the GTK defines a client area as a different
75 widget from the actual widget you are handling. Last but not least some
76 special classes (e.g. wxFrame) handle different categories of widgets and
77 still have the possibility to draw something in the client area.
78 It was therefore required to write a special purpose GTK widget, that would
79 represent a client area in the sense of wxWindows capable to do the jobs
80 2), 3) and 4). I have written this class and it resides in win_gtk.c of
83 All windows must have a widget, with which they interact with other under-
84 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
85 thw wxWindow class has a member variable called m_widget which holds a
86 pointer to this widget. When the window class represents a GTK native widget,
87 this is (in most cases) the only GTK widget the class manages. E.g. the
88 wxStatitText class handles only a GtkLabel widget a pointer to which you
89 can find in m_widget (defined in wxWindow)
91 When the class has a client area for drawing into and for containing children
92 it has to handle the client area widget (of the type GtkMyFixed, defined in
93 win_gtk.c), but there could be any number of widgets, handled by a class
94 The common rule for all windows is only, that the widget that interacts with
95 the rest of GTK must be referenced in m_widget and all other widgets must be
96 children of this widget on the GTK level. The top-most widget, which also
97 represents the client area, must be in the m_wxwindow field and must be of
100 As I said, the window classes that display a GTK native widget only have
101 one widget, so in the case of e.g. the wxButton class m_widget holds a
102 pointer to a GtkButton widget. But windows with client areas (for drawing
103 and children) have a m_widget field that is a pointer to a GtkScrolled-
104 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
105 one is (in the GTK sense) a child of the GtkScrolledWindow.
107 If the m_wxwindow field is set, then all input to this widget is inter-
108 cepted and sent to the wxWindows class. If not, all input to the widget
109 that gets pointed to by m_widget gets intercepted and sent to the class.
113 //-------------------------------------------------------------------------
114 // conditional compilation
115 //-------------------------------------------------------------------------
117 #if (GTK_MINOR_VERSION == 1)
118 #if (GTK_MICRO_VERSION >= 5)
119 #define NEW_GTK_SCROLL_CODE
123 //-----------------------------------------------------------------------------
125 //-----------------------------------------------------------------------------
129 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
130 GdkEvent
*WXUNUSED(event
),
133 printf( "FOCUS NOW AT: " );
140 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
148 char *s
= new char[tmp
.Length()+1];
150 strcpy( s
, WXSTRINGCAST tmp
);
152 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
153 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
158 //-----------------------------------------------------------------------------
160 //-----------------------------------------------------------------------------
162 extern wxList wxPendingDelete
;
163 extern wxList wxTopLevelWindows
;
164 extern bool g_blockEventsOnDrag
;
165 extern bool g_blockEventsOnScroll
;
166 static bool g_capturing
= FALSE
;
167 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
169 // hack: we need something to pass to gtk_menu_popup, so we store the time of
170 // the last click here
171 static guint32 gs_timeLastClick
= 0;
173 //-----------------------------------------------------------------------------
174 // "expose_event" (of m_wxwindow, not of m_widget)
175 //-----------------------------------------------------------------------------
177 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
179 if (!win
->HasVMT()) return;
181 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
183 gdk_event
->area
.width
,
184 gdk_event
->area
.height
);
186 if (gdk_event
->count
> 0) return;
189 printf( "OnExpose from " );
190 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
191 printf( win->GetClassInfo()->GetClassName() );
195 wxPaintEvent
event( win
->GetId() );
196 event
.SetEventObject( win
);
197 win
->GetEventHandler()->ProcessEvent( event
);
199 win
->m_updateRegion
.Clear();
202 //-----------------------------------------------------------------------------
203 // "draw" (of m_wxwindow, not of m_widget)
204 //-----------------------------------------------------------------------------
206 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
208 if (!win
->HasVMT()) return;
210 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
212 wxPaintEvent
event( win
->GetId() );
213 event
.SetEventObject( win
);
214 win
->GetEventHandler()->ProcessEvent( event
);
216 win
->m_updateRegion
.Clear();
219 //-----------------------------------------------------------------------------
220 // "key_press_event" from any window
221 //-----------------------------------------------------------------------------
223 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
225 if (!win
->HasVMT()) return FALSE
;
226 if (g_blockEventsOnDrag
) return FALSE
;
229 printf( "OnKeyPress from " );
230 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
231 printf( win->GetClassInfo()->GetClassName() );
236 switch (gdk_event
->keyval
)
238 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
239 case GDK_Tab
: key_code
= WXK_TAB
; break;
240 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
241 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
242 case GDK_Return
: key_code
= WXK_RETURN
; break;
243 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
244 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
245 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
246 case GDK_Delete
: key_code
= WXK_DELETE
; break;
247 case GDK_Home
: key_code
= WXK_HOME
; break;
248 case GDK_Left
: key_code
= WXK_LEFT
; break;
249 case GDK_Up
: key_code
= WXK_UP
; break;
250 case GDK_Right
: key_code
= WXK_RIGHT
; break;
251 case GDK_Down
: key_code
= WXK_DOWN
; break;
252 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
253 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
254 case GDK_Next
: key_code
= WXK_NEXT
; break;
255 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
256 case GDK_End
: key_code
= WXK_END
; break;
257 case GDK_Begin
: key_code
= WXK_HOME
; break;
258 case GDK_Select
: key_code
= WXK_SELECT
; break;
259 case GDK_Print
: key_code
= WXK_PRINT
; break;
260 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
261 case GDK_Insert
: key_code
= WXK_INSERT
; break;
262 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
263 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
264 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
265 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
266 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
267 case GDK_KP_Up
: key_code
= WXK_UP
; break;
268 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
269 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
270 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
271 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
272 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
273 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
274 case GDK_KP_End
: key_code
= WXK_END
; break;
275 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
276 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
277 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
278 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
279 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
280 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
281 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
282 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
283 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
284 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
285 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
286 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
287 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
288 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
289 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
290 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
291 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
292 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
293 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
294 case GDK_F1
: key_code
= WXK_F1
; break;
295 case GDK_F2
: key_code
= WXK_F2
; break;
296 case GDK_F3
: key_code
= WXK_F3
; break;
297 case GDK_F4
: key_code
= WXK_F4
; break;
298 case GDK_F5
: key_code
= WXK_F5
; break;
299 case GDK_F6
: key_code
= WXK_F6
; break;
300 case GDK_F7
: key_code
= WXK_F7
; break;
301 case GDK_F8
: key_code
= WXK_F8
; break;
302 case GDK_F9
: key_code
= WXK_F9
; break;
303 case GDK_F10
: key_code
= WXK_F10
; break;
304 case GDK_F11
: key_code
= WXK_F11
; break;
305 case GDK_F12
: key_code
= WXK_F12
; break;
308 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
309 key_code
= gdk_event
->keyval
;
313 if (!key_code
) return FALSE
;
315 wxKeyEvent
event( wxEVT_CHAR
);
316 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
317 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
318 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
319 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
320 event
.m_keyCode
= key_code
;
323 event
.SetEventObject( win
);
325 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
329 wxWindow
*ancestor
= win
;
332 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
335 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
336 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
339 ancestor
= ancestor
->GetParent();
343 // win is a control: tab can be propagated up
344 if ((!ret
) && (gdk_event
->keyval
== GDK_Tab
))
346 wxNavigationKeyEvent new_event
;
347 new_event
.SetDirection( !(gdk_event
->state
& GDK_SHIFT_MASK
) );
348 new_event
.SetWindowChange( FALSE
);
349 new_event
.SetCurrentFocus( win
);
350 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
354 // win is a panel: up can be propagated to the panel
355 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
356 (gdk_event->keyval == GDK_Up))
358 win->m_parent->SetFocus();
362 // win is a panel: left/right can be propagated to the panel
363 if ((!ret) && (win->m_wxwindow) &&
364 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
365 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
367 wxNavigationKeyEvent new_event;
368 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
369 new_event.SetCurrentFocus( win );
370 ret = win->GetEventHandler()->ProcessEvent( new_event );
376 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
382 //-----------------------------------------------------------------------------
383 // "button_press_event"
384 //-----------------------------------------------------------------------------
386 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
388 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
390 if (g_blockEventsOnDrag
) return TRUE
;
391 if (g_blockEventsOnScroll
) return TRUE
;
395 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
397 gtk_widget_grab_focus (win
->m_wxwindow
);
400 printf( "GrabFocus from " );
401 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
402 printf( win->GetClassInfo()->GetClassName() );
409 if (!win
->HasVMT()) return TRUE
;
412 printf( "OnButtonPress from " );
413 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
414 printf( win->GetClassInfo()->GetClassName() );
418 wxEventType event_type
= wxEVT_LEFT_DOWN
;
420 if (gdk_event
->button
== 1)
422 switch (gdk_event
->type
)
424 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
425 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
429 else if (gdk_event
->button
== 2)
431 switch (gdk_event
->type
)
433 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
434 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
438 else if (gdk_event
->button
== 3)
440 switch (gdk_event
->type
)
442 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
443 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
448 wxMouseEvent
event( event_type
);
449 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
450 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
451 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
452 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
453 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
454 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
455 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
457 event
.m_x
= (long)gdk_event
->x
;
458 event
.m_y
= (long)gdk_event
->y
;
460 // Some control don't have their own X window and thus cannot get
465 wxNode
*node
= win
->GetChildren().First();
468 wxWindow
*child
= (wxWindow
*)node
->Data();
470 if (child
->m_isStaticBox
)
472 // wxStaticBox is transparent in the box itself
475 int xx1
= child
->m_x
;
476 int yy1
= child
->m_y
;
477 int xx2
= child
->m_x
+ child
->m_width
;
478 int yy2
= child
->m_x
+ child
->m_height
;
481 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
483 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
485 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
487 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
490 event
.m_x
-= child
->m_x
;
491 event
.m_y
-= child
->m_y
;
498 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
499 (child
->m_x
<= event
.m_x
) &&
500 (child
->m_y
<= event
.m_y
) &&
501 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
502 (child
->m_y
+child
->m_height
>= event
.m_y
))
505 event
.m_x
-= child
->m_x
;
506 event
.m_y
-= child
->m_y
;
514 event
.SetEventObject( win
);
516 gs_timeLastClick
= gdk_event
->time
;
518 if (win
->GetEventHandler()->ProcessEvent( event
))
519 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
524 //-----------------------------------------------------------------------------
525 // "button_release_event"
526 //-----------------------------------------------------------------------------
528 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
530 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
532 if (g_blockEventsOnDrag
) return TRUE
;
533 if (g_blockEventsOnScroll
) return TRUE
;
535 if (!win
->HasVMT()) return TRUE
;
538 printf( "OnButtonRelease from " );
539 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
540 printf( win->GetClassInfo()->GetClassName() );
544 wxEventType event_type
= wxEVT_NULL
;
546 switch (gdk_event
->button
)
548 case 1: event_type
= wxEVT_LEFT_UP
; break;
549 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
550 case 3: event_type
= wxEVT_RIGHT_UP
; break;
553 wxMouseEvent
event( event_type
);
554 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
555 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
556 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
557 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
558 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
559 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
560 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
561 event
.m_x
= (long)gdk_event
->x
;
562 event
.m_y
= (long)gdk_event
->y
;
564 // Some control don't have their own X window and thus cannot get
569 wxNode
*node
= win
->GetChildren().First();
572 wxWindow
*child
= (wxWindow
*)node
->Data();
574 if (child
->m_isStaticBox
)
576 // wxStaticBox is transparent in the box itself
579 int xx1
= child
->m_x
;
580 int yy1
= child
->m_y
;
581 int xx2
= child
->m_x
+ child
->m_width
;
582 int yy2
= child
->m_x
+ child
->m_height
;
585 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
587 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
589 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
591 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
594 event
.m_x
-= child
->m_x
;
595 event
.m_y
-= child
->m_y
;
602 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
603 (child
->m_x
<= event
.m_x
) &&
604 (child
->m_y
<= event
.m_y
) &&
605 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
606 (child
->m_y
+child
->m_height
>= event
.m_y
))
609 event
.m_x
-= child
->m_x
;
610 event
.m_y
-= child
->m_y
;
618 event
.SetEventObject( win
);
620 if (win
->GetEventHandler()->ProcessEvent( event
))
621 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
626 //-----------------------------------------------------------------------------
627 // "motion_notify_event"
628 //-----------------------------------------------------------------------------
630 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
632 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
634 if (g_blockEventsOnDrag
) return TRUE
;
635 if (g_blockEventsOnScroll
) return TRUE
;
637 if (!win
->HasVMT()) return TRUE
;
640 printf( "OnMotion from " );
641 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
642 printf( win->GetClassInfo()->GetClassName() );
646 wxMouseEvent
event( wxEVT_MOTION
);
647 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
648 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
649 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
650 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
651 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
652 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
653 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
655 event
.m_x
= (long)gdk_event
->x
;
656 event
.m_y
= (long)gdk_event
->y
;
658 // Some control don't have their own X window and thus cannot get
663 wxNode
*node
= win
->GetChildren().First();
666 wxWindow
*child
= (wxWindow
*)node
->Data();
668 if (child
->m_isStaticBox
)
670 // wxStaticBox is transparent in the box itself
673 int xx1
= child
->m_x
;
674 int yy1
= child
->m_y
;
675 int xx2
= child
->m_x
+ child
->m_width
;
676 int yy2
= child
->m_x
+ child
->m_height
;
679 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
681 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
683 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
685 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
688 event
.m_x
-= child
->m_x
;
689 event
.m_y
-= child
->m_y
;
696 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
697 (child
->m_x
<= event
.m_x
) &&
698 (child
->m_y
<= event
.m_y
) &&
699 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
700 (child
->m_y
+child
->m_height
>= event
.m_y
))
703 event
.m_x
-= child
->m_x
;
704 event
.m_y
-= child
->m_y
;
712 event
.SetEventObject( win
);
714 if (win
->GetEventHandler()->ProcessEvent( event
))
715 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
720 //-----------------------------------------------------------------------------
722 //-----------------------------------------------------------------------------
724 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
726 if (g_blockEventsOnDrag
) return TRUE
;
732 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
734 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
736 printf( "SetFocus flag from " );
737 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
738 printf( win->GetClassInfo()->GetClassName() );
744 if (!win
->HasVMT()) return TRUE
;
747 printf( "OnSetFocus from " );
748 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
749 printf( win->GetClassInfo()->GetClassName() );
751 printf( WXSTRINGCAST win->GetLabel() );
755 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
756 event
.SetEventObject( win
);
758 if (win
->GetEventHandler()->ProcessEvent( event
))
759 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
764 //-----------------------------------------------------------------------------
766 //-----------------------------------------------------------------------------
768 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
770 if (g_blockEventsOnDrag
) return TRUE
;
773 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
774 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
777 if (!win
->HasVMT()) return TRUE
;
780 printf( "OnKillFocus from " );
781 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
782 printf( win->GetClassInfo()->GetClassName() );
786 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
787 event
.SetEventObject( win
);
789 if (win
->GetEventHandler()->ProcessEvent( event
))
790 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
795 //-----------------------------------------------------------------------------
796 // "enter_notify_event"
797 //-----------------------------------------------------------------------------
799 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
801 if (g_blockEventsOnDrag
) return TRUE
;
803 if ((widget
->window
) && (win
->m_cursor
))
804 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
806 if (widget
->window
!= gdk_event
->window
) return TRUE
;
808 if (!win
->HasVMT()) return TRUE
;
811 printf( "OnEnter from " );
812 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
813 printf( win->GetClassInfo()->GetClassName() );
817 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
818 event
.SetEventObject( win
);
822 GdkModifierType state
= (GdkModifierType
)0;
824 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
826 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
827 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
828 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
829 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
830 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
831 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
832 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
837 if (win
->GetEventHandler()->ProcessEvent( event
))
838 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
843 //-----------------------------------------------------------------------------
844 // "leave_notify_event"
845 //-----------------------------------------------------------------------------
847 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
849 if (g_blockEventsOnDrag
) return TRUE
;
851 if ((widget
->window
) && (win
->m_cursor
))
852 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
854 if (widget
->window
!= gdk_event
->window
) return TRUE
;
856 if (!win
->HasVMT()) return TRUE
;
859 printf( "OnLeave from " );
860 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
861 printf( win->GetClassInfo()->GetClassName() );
865 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
866 event
.SetEventObject( win
);
870 GdkModifierType state
= (GdkModifierType
)0;
872 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
874 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
875 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
876 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
877 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
878 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
879 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
880 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
885 if (win
->GetEventHandler()->ProcessEvent( event
))
886 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
891 //-----------------------------------------------------------------------------
892 // "value_changed" from m_vAdjust
893 //-----------------------------------------------------------------------------
895 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
897 if (g_blockEventsOnDrag
) return;
900 printf( "OnVScroll from " );
901 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
902 printf( win->GetClassInfo()->GetClassName() );
906 if (!win
->HasVMT()) return;
908 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
909 if (fabs(diff
) < 0.2) return;
911 wxEventType command
= wxEVT_NULL
;
913 float line_step
= win
->m_vAdjust
->step_increment
;
914 float page_step
= win
->m_vAdjust
->page_increment
;
916 if (win
->m_isScrolling
)
918 command
= wxEVT_SCROLL_THUMBTRACK
;
922 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
923 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
924 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
925 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
926 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
927 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
928 else command
= wxEVT_SCROLL_THUMBTRACK
;
931 int value
= (int)(win
->m_vAdjust
->value
+0.5);
933 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
934 event
.SetEventObject( win
);
935 win
->GetEventHandler()->ProcessEvent( event
);
938 //-----------------------------------------------------------------------------
939 // "value_changed" from m_hAdjust
940 //-----------------------------------------------------------------------------
942 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
944 if (g_blockEventsOnDrag
) return;
947 printf( "OnHScroll from " );
948 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
949 printf( win->GetClassInfo()->GetClassName() );
953 if (!win
->HasVMT()) return;
955 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
956 if (fabs(diff
) < 0.2) return;
958 wxEventType command
= wxEVT_NULL
;
960 float line_step
= win
->m_hAdjust
->step_increment
;
961 float page_step
= win
->m_hAdjust
->page_increment
;
963 if (win
->m_isScrolling
)
965 command
= wxEVT_SCROLL_THUMBTRACK
;
969 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
970 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
971 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
972 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
973 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
974 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
975 else command
= wxEVT_SCROLL_THUMBTRACK
;
978 int value
= (int)(win
->m_hAdjust
->value
+0.5);
980 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
981 event
.SetEventObject( win
);
982 win
->GetEventHandler()->ProcessEvent( event
);
985 //-----------------------------------------------------------------------------
986 // "changed" from m_vAdjust
987 //-----------------------------------------------------------------------------
989 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
991 if (g_blockEventsOnDrag
) return;
994 printf( "OnVScroll change from " );
995 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
996 printf( win->GetClassInfo()->GetClassName() );
1000 if (!win
->HasVMT()) return;
1002 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1003 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1005 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1006 event
.SetEventObject( win
);
1007 win
->GetEventHandler()->ProcessEvent( event
);
1010 //-----------------------------------------------------------------------------
1011 // "changed" from m_hAdjust
1012 //-----------------------------------------------------------------------------
1014 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1016 if (g_blockEventsOnDrag
) return;
1019 printf( "OnHScroll change from " );
1020 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1021 printf( win->GetClassInfo()->GetClassName() );
1025 if (!win
->HasVMT()) return;
1027 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1028 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1030 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1031 event
.SetEventObject( win
);
1032 win
->GetEventHandler()->ProcessEvent( event
);
1035 //-----------------------------------------------------------------------------
1036 // "button_press_event" from scrollbar
1037 //-----------------------------------------------------------------------------
1039 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1040 GdkEventButton
*WXUNUSED(gdk_event
),
1043 // don't test here as we can release the mouse while being over
1044 // a different window then the slider
1046 // if (gdk_event->window != widget->slider) return FALSE;
1048 win
->m_isScrolling
= TRUE
;
1049 g_blockEventsOnScroll
= TRUE
;
1054 //-----------------------------------------------------------------------------
1055 // "button_release_event" from scrollbar
1056 //-----------------------------------------------------------------------------
1058 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1059 GdkEventButton
*WXUNUSED(gdk_event
),
1063 // don't test here as we can release the mouse while being over
1064 // a different window then the slider
1066 // if (gdk_event->window != widget->slider) return FALSE;
1068 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1070 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1071 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1073 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1075 win
->m_isScrolling
= FALSE
;
1076 g_blockEventsOnScroll
= FALSE
;
1081 //-----------------------------------------------------------------------------
1082 // InsertChild for wxWindow.
1083 //-----------------------------------------------------------------------------
1085 // Callback for wxWindow. This very strange beast has to be used because
1086 // C++ has no virtual methods in a constructor. We have to emulate a
1087 // virtual function here as wxNotebook requires a different way to insert
1088 // a child in it. I had opted for creating a wxNotebookPage window class
1089 // which would have made this superfluous (such in the MDI window system),
1090 // but no-one was listening to me...
1092 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1094 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1095 GTK_WIDGET(child
->m_widget
),
1099 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1104 //-----------------------------------------------------------------------------
1106 //-----------------------------------------------------------------------------
1108 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1110 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1111 EVT_SIZE(wxWindow::OnSize
)
1112 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1113 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1114 EVT_IDLE(wxWindow::OnIdle
)
1117 wxWindow::wxWindow()
1119 m_widget
= (GtkWidget
*) NULL
;
1120 m_wxwindow
= (GtkWidget
*) NULL
;
1121 m_parent
= (wxWindow
*) NULL
;
1122 m_children
.DeleteContents( FALSE
);
1135 m_eventHandler
= this;
1136 m_windowValidator
= (wxValidator
*) NULL
;
1140 m_cursor
= (wxCursor
*) NULL
;
1141 m_font
= *wxSWISS_FONT
;
1143 m_windowName
= "noname";
1145 m_constraints
= (wxLayoutConstraints
*) NULL
;
1146 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1147 m_windowSizer
= (wxSizer
*) NULL
;
1148 m_sizerParent
= (wxWindow
*) NULL
;
1149 m_autoLayout
= FALSE
;
1153 m_needParent
= TRUE
;
1155 m_hasScrolling
= FALSE
;
1156 m_isScrolling
= FALSE
;
1157 m_hAdjust
= (GtkAdjustment
*) NULL
;
1158 m_vAdjust
= (GtkAdjustment
*) NULL
;
1159 m_oldHorizontalPos
= 0.0;
1160 m_oldVerticalPos
= 0.0;
1165 m_dropTarget
= (wxDropTarget
*) NULL
;
1167 m_scrollGC
= (GdkGC
*) NULL
;
1168 m_widgetStyle
= (GtkStyle
*) NULL
;
1170 m_insertCallback
= wxInsertChildInWindow
;
1172 m_clientObject
= (wxClientData
*) NULL
;
1173 m_clientData
= NULL
;
1175 m_isStaticBox
= FALSE
;
1176 m_acceptsFocus
= FALSE
;
1179 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1180 const wxPoint
&pos
, const wxSize
&size
,
1181 long style
, const wxString
&name
)
1183 m_insertCallback
= wxInsertChildInWindow
;
1184 Create( parent
, id
, pos
, size
, style
, name
);
1187 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1188 const wxPoint
&pos
, const wxSize
&size
,
1189 long style
, const wxString
&name
)
1193 m_needParent
= TRUE
;
1195 PreCreation( parent
, id
, pos
, size
, style
, name
);
1197 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1198 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1201 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1204 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1207 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1208 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1211 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1212 scroll_class
->scrollbar_spacing
= 0;
1214 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1216 m_oldHorizontalPos
= 0.0;
1217 m_oldVerticalPos
= 0.0;
1219 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1220 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1222 m_wxwindow
= gtk_myfixed_new();
1225 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1228 #ifdef NEW_GTK_SCROLL_CODE
1229 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1230 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1232 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1233 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1237 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1240 if (m_windowStyle
& wxRAISED_BORDER
)
1242 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1244 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1246 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1250 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1253 if ((m_windowStyle
& wxTAB_TRAVERSAL
) != 0)
1255 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1256 m_acceptsFocus
= FALSE
;
1260 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1261 m_acceptsFocus
= TRUE
;
1264 // shut the viewport up
1265 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1266 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1268 // I _really_ don't want scrollbars in the beginning
1269 m_vAdjust
->lower
= 0.0;
1270 m_vAdjust
->upper
= 1.0;
1271 m_vAdjust
->value
= 0.0;
1272 m_vAdjust
->step_increment
= 1.0;
1273 m_vAdjust
->page_increment
= 1.0;
1274 m_vAdjust
->page_size
= 5.0;
1275 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1276 m_hAdjust
->lower
= 0.0;
1277 m_hAdjust
->upper
= 1.0;
1278 m_hAdjust
->value
= 0.0;
1279 m_hAdjust
->step_increment
= 1.0;
1280 m_hAdjust
->page_increment
= 1.0;
1281 m_hAdjust
->page_size
= 5.0;
1282 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1284 // these handlers block mouse events to any window during scrolling
1285 // such as motion events and prevent GTK and wxWindows from fighting
1286 // over where the slider should be
1288 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1289 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1291 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1292 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1294 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1295 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1297 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1298 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1300 // these handers het notified when screen updates are required either when
1301 // scrolling or when the window size (and therefore scrollbar configuration)
1304 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1305 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1306 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1307 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1309 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1310 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1311 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1312 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1314 gtk_widget_show( m_wxwindow
);
1316 if (m_parent
) m_parent
->AddChild( this );
1318 (m_parent
->m_insertCallback
)( m_parent
, this );
1327 wxWindow::~wxWindow()
1331 if (m_dropTarget
) delete m_dropTarget
;
1333 if (m_parent
) m_parent
->RemoveChild( this );
1334 if (m_widget
) Show( FALSE
);
1338 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1340 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1342 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1344 if (m_widget
) gtk_widget_destroy( m_widget
);
1346 if (m_cursor
) delete m_cursor
;
1348 DeleteRelatedConstraints();
1351 // This removes any dangling pointers to this window
1352 // in other windows' constraintsInvolvedIn lists.
1353 UnsetConstraints(m_constraints
);
1354 delete m_constraints
;
1355 m_constraints
= (wxLayoutConstraints
*) NULL
;
1359 delete m_windowSizer
;
1360 m_windowSizer
= (wxSizer
*) NULL
;
1362 // If this is a child of a sizer, remove self from parent
1363 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1365 // Just in case the window has been Closed, but
1366 // we're then deleting immediately: don't leave
1367 // dangling pointers.
1368 wxPendingDelete
.DeleteObject(this);
1370 // Just in case we've loaded a top-level window via
1371 // wxWindow::LoadNativeDialog but we weren't a dialog
1373 wxTopLevelWindows
.DeleteObject(this);
1375 if (m_windowValidator
) delete m_windowValidator
;
1377 if (m_clientObject
) delete m_clientObject
;
1380 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1381 const wxPoint
&pos
, const wxSize
&size
,
1382 long style
, const wxString
&name
)
1384 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1386 m_widget
= (GtkWidget
*) NULL
;
1387 m_wxwindow
= (GtkWidget
*) NULL
;
1390 m_children
.DeleteContents( FALSE
);
1393 if (m_width
== -1) m_width
= 20;
1395 if (m_height
== -1) m_height
= 20;
1400 if (!m_needParent
) // some reasonable defaults
1404 m_x
= (gdk_screen_width () - m_width
) / 2;
1405 if (m_x
< 10) m_x
= 10;
1409 m_y
= (gdk_screen_height () - m_height
) / 2;
1410 if (m_y
< 10) m_y
= 10;
1421 m_eventHandler
= this;
1423 m_windowId
= id
== -1 ? wxNewId() : id
;
1427 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1428 m_font
= *wxSWISS_FONT
;
1429 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1430 m_foregroundColour
= *wxBLACK
;
1431 m_windowStyle
= style
;
1432 m_windowName
= name
;
1434 m_constraints
= (wxLayoutConstraints
*) NULL
;
1435 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1436 m_windowSizer
= (wxSizer
*) NULL
;
1437 m_sizerParent
= (wxWindow
*) NULL
;
1438 m_autoLayout
= FALSE
;
1440 m_hasScrolling
= FALSE
;
1441 m_isScrolling
= FALSE
;
1442 m_hAdjust
= (GtkAdjustment
*) NULL
;
1443 m_vAdjust
= (GtkAdjustment
*) NULL
;
1444 m_oldHorizontalPos
= 0.0;
1445 m_oldVerticalPos
= 0.0;
1450 m_dropTarget
= (wxDropTarget
*) NULL
;
1452 m_windowValidator
= (wxValidator
*) NULL
;
1453 m_scrollGC
= (GdkGC
*) NULL
;
1454 m_widgetStyle
= (GtkStyle
*) NULL
;
1456 m_clientObject
= (wxClientData
*)NULL
;
1457 m_clientData
= NULL
;
1459 m_isStaticBox
= FALSE
;
1462 void wxWindow::PostCreation()
1466 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1467 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1469 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1470 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1473 ConnectWidget( GetConnectWidget() );
1475 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1477 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1479 SetCursor( *wxSTANDARD_CURSOR
);
1484 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1486 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1487 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1489 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1490 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1492 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1493 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1495 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1496 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1498 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1499 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1501 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1502 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1504 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1505 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1507 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1508 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1511 bool wxWindow::HasVMT()
1516 bool wxWindow::Close( bool force
)
1518 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1520 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1521 event
.SetEventObject(this);
1522 event
.SetForce(force
);
1524 return GetEventHandler()->ProcessEvent(event
);
1527 bool wxWindow::Destroy()
1529 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1536 bool wxWindow::DestroyChildren()
1539 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1542 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1545 if (m_children
.Member(child
)) delete node
;
1551 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1553 // are we to set fonts here ?
1556 wxPoint
wxWindow::GetClientAreaOrigin() const
1558 return wxPoint(0,0);
1561 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1563 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1565 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1571 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1573 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1574 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1576 if (m_resizing
) return; // I don't like recursions
1579 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1581 // don't set the size for children of wxNotebook, just take the values.
1589 int old_width
= m_width
;
1590 int old_height
= m_height
;
1592 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1594 if (x
!= -1) m_x
= x
;
1595 if (y
!= -1) m_y
= y
;
1596 if (width
!= -1) m_width
= width
;
1597 if (height
!= -1) m_height
= height
;
1607 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1609 if (width
== -1) m_width
= 80;
1612 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1614 if (height
== -1) m_height
= 26;
1617 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1618 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1619 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_minWidth
;
1620 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_minHeight
;
1622 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1623 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1625 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1626 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1631 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1632 event
.SetEventObject( this );
1633 GetEventHandler()->ProcessEvent( event
);
1638 void wxWindow::SetSize( int width
, int height
)
1640 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1643 void wxWindow::Move( int x
, int y
)
1645 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1648 void wxWindow::GetSize( int *width
, int *height
) const
1650 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1652 if (width
) (*width
) = m_width
;
1653 if (height
) (*height
) = m_height
;
1656 void wxWindow::SetClientSize( int width
, int height
)
1658 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1662 SetSize( width
, height
);
1669 if (!m_hasScrolling
)
1671 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1673 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1674 (m_windowStyle
& wxSUNKEN_BORDER
))
1676 dw
+= 2 * window_class
->xthickness
;
1677 dh
+= 2 * window_class
->ythickness
;
1682 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1683 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1685 #ifdef NEW_GTK_SCROLL_CODE
1686 GtkWidget
*viewport
= scroll_window
->child
;
1688 GtkWidget
*viewport
= scroll_window
->viewport
;
1691 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1693 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1694 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1696 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1697 (m_windowStyle
& wxSUNKEN_BORDER
))
1699 dw
+= 2 * viewport_class
->xthickness
;
1700 dh
+= 2 * viewport_class
->ythickness
;
1703 if (scroll_window
->vscrollbar_visible
)
1705 dw
+= vscrollbar
->allocation
.width
;
1706 dw
+= scroll_class
->scrollbar_spacing
;
1709 if (scroll_window
->hscrollbar_visible
)
1711 dh
+= hscrollbar
->allocation
.height
;
1712 dw
+= scroll_class
->scrollbar_spacing
;
1716 SetSize( width
+dw
, height
+dh
);
1720 void wxWindow::GetClientSize( int *width
, int *height
) const
1722 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1726 if (width
) (*width
) = m_width
;
1727 if (height
) (*height
) = m_height
;
1734 if (!m_hasScrolling
)
1736 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1738 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1739 (m_windowStyle
& wxSUNKEN_BORDER
))
1741 dw
+= 2 * window_class
->xthickness
;
1742 dh
+= 2 * window_class
->ythickness
;
1747 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1748 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1750 #ifdef NEW_GTK_SCROLL_CODE
1751 GtkWidget
*viewport
= scroll_window
->child
;
1753 GtkWidget
*viewport
= scroll_window
->viewport
;
1756 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1758 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1759 (m_windowStyle
& wxSUNKEN_BORDER
))
1761 dw
+= 2 * viewport_class
->xthickness
;
1762 dh
+= 2 * viewport_class
->ythickness
;
1765 if (scroll_window
->vscrollbar_visible
)
1767 // dw += vscrollbar->allocation.width;
1768 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1769 dw
+= scroll_class
->scrollbar_spacing
;
1772 if (scroll_window
->hscrollbar_visible
)
1774 // dh += hscrollbar->allocation.height;
1776 dh
+= scroll_class
->scrollbar_spacing
;
1780 if (width
) (*width
) = m_width
- dw
;
1781 if (height
) (*height
) = m_height
- dh
;
1785 void wxWindow::GetPosition( int *x
, int *y
) const
1787 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1793 void wxWindow::ClientToScreen( int *x
, int *y
)
1795 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1797 GdkWindow
*source
= (GdkWindow
*) NULL
;
1799 source
= m_wxwindow
->window
;
1801 source
= m_widget
->window
;
1805 gdk_window_get_origin( source
, &org_x
, &org_y
);
1809 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1811 org_x
+= m_widget
->allocation
.x
;
1812 org_y
+= m_widget
->allocation
.y
;
1816 wxPoint
pt(GetClientAreaOrigin());
1824 void wxWindow::ScreenToClient( int *x
, int *y
)
1826 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1828 GdkWindow
*source
= (GdkWindow
*) NULL
;
1830 source
= m_wxwindow
->window
;
1832 source
= m_widget
->window
;
1836 gdk_window_get_origin( source
, &org_x
, &org_y
);
1840 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1842 org_x
+= m_widget
->allocation
.x
;
1843 org_y
+= m_widget
->allocation
.y
;
1847 wxPoint
pt(GetClientAreaOrigin());
1855 void wxWindow::Centre( int direction
)
1857 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1866 m_parent
->GetSize( &p_w
, &p_h
);
1867 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
1868 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
1872 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
1873 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
1879 void wxWindow::Fit()
1881 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1885 wxNode
*node
= m_children
.First();
1888 wxWindow
*win
= (wxWindow
*)node
->Data();
1890 win
->GetPosition(&wx
, &wy
);
1891 win
->GetSize(&ww
, &wh
);
1892 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
1893 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
1895 node
= node
->Next();
1898 SetClientSize(maxX
+ 7, maxY
+ 14);
1901 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1903 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1911 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1913 // if (GetAutoLayout()) Layout();
1916 bool wxWindow::Show( bool show
)
1918 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
1921 gtk_widget_show( m_widget
);
1923 gtk_widget_hide( m_widget
);
1930 void wxWindow::Enable( bool enable
)
1932 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1934 m_isEnabled
= enable
;
1936 gtk_widget_set_sensitive( m_widget
, enable
);
1937 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1940 int wxWindow::GetCharHeight() const
1942 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
1944 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
1946 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1948 return font
->ascent
+ font
->descent
;
1951 int wxWindow::GetCharWidth() const
1953 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
1955 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
1957 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1959 return gdk_string_width( font
, "H" );
1962 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1963 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1965 wxFont fontToUse
= m_font
;
1966 if (theFont
) fontToUse
= *theFont
;
1968 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
1970 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1971 if (x
) (*x
) = gdk_string_width( font
, string
);
1972 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1973 if (descent
) (*descent
) = font
->descent
;
1974 if (externalLeading
) (*externalLeading
) = 0; // ??
1977 void wxWindow::MakeModal( bool modal
)
1981 // Disable all other windows
1982 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1984 wxNode
*node
= wxTopLevelWindows
.First();
1987 wxWindow
*win
= (wxWindow
*)node
->Data();
1988 if (win
!= this) win
->Enable(!modal
);
1990 node
= node
->Next();
1995 void wxWindow::SetFocus()
1997 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1999 GtkWidget
*connect_widget
= GetConnectWidget();
2002 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2004 gtk_widget_grab_focus (connect_widget
);
2006 else if (GTK_IS_CONTAINER(connect_widget
))
2008 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2016 wxWindow
*wxWindow::FindFocus()
2018 return g_focusWindow
;
2021 bool wxWindow::AcceptsFocus() const
2023 return IsEnabled() && IsShown() && m_acceptsFocus
;
2026 bool wxWindow::OnClose()
2031 void wxWindow::AddChild( wxWindow
*child
)
2033 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2034 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2036 m_children
.Append( child
);
2039 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2041 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2043 wxWindow
*oldParent
= GetParent();
2045 if (oldParent
) oldParent
->RemoveChild( this );
2047 gtk_widget_unparent( m_widget
);
2051 newParent
->AddChild( this );
2052 (newParent
->m_insertCallback
)( newParent
, this );
2058 void wxWindow::RemoveChild( wxWindow
*child
)
2060 m_children
.DeleteObject( child
);
2061 child
->m_parent
= (wxWindow
*) NULL
;
2064 void wxWindow::SetReturnCode( int retCode
)
2066 m_retCode
= retCode
;
2069 int wxWindow::GetReturnCode()
2074 void wxWindow::Raise()
2076 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2078 if (m_widget
) gdk_window_raise( m_widget
->window
);
2081 void wxWindow::Lower()
2083 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2085 if (m_widget
) gdk_window_lower( m_widget
->window
);
2088 wxEvtHandler
*wxWindow::GetEventHandler() const
2090 return m_eventHandler
;
2093 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2095 m_eventHandler
= handler
;
2098 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2100 handler
->SetNextHandler(GetEventHandler());
2101 SetEventHandler(handler
);
2104 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2106 if (GetEventHandler())
2108 wxEvtHandler
*handlerA
= GetEventHandler();
2109 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2110 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2111 SetEventHandler(handlerB
);
2115 return (wxEvtHandler
*) NULL
;
2121 return (wxEvtHandler
*) NULL
;
2124 wxValidator
*wxWindow::GetValidator()
2126 return m_windowValidator
;
2129 void wxWindow::SetValidator( const wxValidator
& validator
)
2131 if (m_windowValidator
) delete m_windowValidator
;
2132 m_windowValidator
= validator
.Clone();
2133 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2136 void wxWindow::SetClientObject( wxClientData
*data
)
2138 if (m_clientObject
) delete m_clientObject
;
2139 m_clientObject
= data
;
2142 wxClientData
*wxWindow::GetClientObject()
2144 return m_clientObject
;
2147 void wxWindow::SetClientData( void *data
)
2149 m_clientData
= data
;
2152 void *wxWindow::GetClientData()
2154 return m_clientData
;
2157 bool wxWindow::IsBeingDeleted()
2162 void wxWindow::SetId( wxWindowID id
)
2167 wxWindowID
wxWindow::GetId() const
2172 void wxWindow::SetCursor( const wxCursor
&cursor
)
2174 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2178 if (cursor
== *m_cursor
) return;
2183 *m_cursor
= *wxSTANDARD_CURSOR
;
2186 if ((m_widget
) && (m_widget
->window
))
2187 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2189 if ((m_wxwindow
) && (m_wxwindow
->window
))
2190 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2193 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2198 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2200 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2202 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2206 gdk_window_clear_area( m_wxwindow
->window
,
2220 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2222 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2226 GdkRectangle gdk_rect
;
2227 gdk_rect
.x
= rect
->x
;
2228 gdk_rect
.y
= rect
->y
;
2229 gdk_rect
.width
= rect
->width
;
2230 gdk_rect
.height
= rect
->height
;
2233 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2235 gtk_widget_draw( m_widget
, &gdk_rect
);
2239 wxRegion
wxWindow::GetUpdateRegion() const
2241 return m_updateRegion
;
2244 bool wxWindow::IsExposed( int x
, int y
) const
2246 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2249 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2251 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2254 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2256 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2259 bool wxWindow::IsExposed( const wxRect
& rect
) const
2261 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2264 void wxWindow::Clear()
2266 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2268 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2271 wxColour
wxWindow::GetBackgroundColour() const
2273 return m_backgroundColour
;
2276 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2278 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2280 if (m_backgroundColour
== colour
) return;
2282 m_backgroundColour
= colour
;
2283 if (!m_backgroundColour
.Ok()) return;
2287 GdkWindow
*window
= m_wxwindow
->window
;
2288 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2289 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2290 gdk_window_clear( window
);
2293 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2294 if (sysbg
.Red() == colour
.Red() &&
2295 sysbg
.Green() == colour
.Green() &&
2296 sysbg
.Blue() == colour
.Blue())
2298 m_backgroundColour
= wxNullColour
;
2300 m_backgroundColour
= sysbg
;
2308 wxColour
wxWindow::GetForegroundColour() const
2310 return m_foregroundColour
;
2313 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2315 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2317 if (m_foregroundColour
== colour
) return;
2319 m_foregroundColour
= colour
;
2320 if (!m_foregroundColour
.Ok()) return;
2322 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2323 if (sysbg
.Red() == colour
.Red() &&
2324 sysbg
.Green() == colour
.Green() &&
2325 sysbg
.Blue() == colour
.Blue())
2327 m_backgroundColour
= wxNullColour
;
2329 m_backgroundColour
= sysbg
;
2337 GtkStyle
*wxWindow::GetWidgetStyle()
2339 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2343 gtk_widget_get_style( m_widget
) );
2345 return m_widgetStyle
;
2348 void wxWindow::SetWidgetStyle()
2350 GtkStyle
*style
= GetWidgetStyle();
2352 gdk_font_unref( style
->font
);
2353 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2355 if (m_foregroundColour
.Ok())
2357 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2358 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2359 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2360 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2363 if (m_backgroundColour
.Ok())
2365 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2366 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2367 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2368 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2369 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2370 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2371 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2372 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2373 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2377 void wxWindow::ApplyWidgetStyle()
2381 bool wxWindow::Validate()
2383 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2385 wxNode
*node
= m_children
.First();
2388 wxWindow
*child
= (wxWindow
*)node
->Data();
2389 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2393 node
= node
->Next();
2398 bool wxWindow::TransferDataToWindow()
2400 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2402 wxNode
*node
= m_children
.First();
2405 wxWindow
*child
= (wxWindow
*)node
->Data();
2406 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2407 !child
->GetValidator()->TransferToWindow() )
2409 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2412 node
= node
->Next();
2417 bool wxWindow::TransferDataFromWindow()
2419 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2421 wxNode
*node
= m_children
.First();
2424 wxWindow
*child
= (wxWindow
*)node
->Data();
2425 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2429 node
= node
->Next();
2434 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2436 m_acceleratorTable
= accel
;
2439 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2441 TransferDataToWindow();
2444 void wxWindow::InitDialog()
2446 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2448 wxInitDialogEvent
event(GetId());
2449 event
.SetEventObject( this );
2450 GetEventHandler()->ProcessEvent(event
);
2453 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2455 menu
->SetInvokingWindow( win
);
2456 wxNode
*node
= menu
->m_items
.First();
2459 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2460 if (menuitem
->IsSubMenu())
2462 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2464 node
= node
->Next();
2468 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2470 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2472 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2474 SetInvokingWindow( menu
, this );
2476 GTK_MENU(menu
->m_menu
),
2477 (GtkWidget
*)NULL
, // parent menu shell
2478 (GtkWidget
*)NULL
, // parent menu item
2479 (GtkMenuPositionFunc
)NULL
,
2480 NULL
, // client data
2481 0, // button used to activate it
2482 0//gs_timeLastClick // the time of activation
2487 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2489 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2491 GtkWidget
*dnd_widget
= GetConnectWidget();
2493 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2495 if (m_dropTarget
) delete m_dropTarget
;
2496 m_dropTarget
= dropTarget
;
2498 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2501 wxDropTarget
*wxWindow::GetDropTarget() const
2503 return m_dropTarget
;
2506 GtkWidget
* wxWindow::GetConnectWidget()
2508 GtkWidget
*connect_widget
= m_widget
;
2509 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2511 return connect_widget
;
2514 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2516 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2517 return (window
== m_widget
->window
);
2520 void wxWindow::SetFont( const wxFont
&font
)
2522 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2524 if (((wxFont
*)&font
)->Ok())
2527 m_font
= *wxSWISS_FONT
;
2529 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2530 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2531 sysbg
.Green() == m_backgroundColour
.Green() &&
2532 sysbg
.Blue() == m_backgroundColour
.Blue())
2534 m_backgroundColour
= wxNullColour
;
2536 m_backgroundColour
= sysbg
;
2544 void wxWindow::SetWindowStyleFlag( long flag
)
2546 m_windowStyle
= flag
;
2549 long wxWindow::GetWindowStyleFlag() const
2551 return m_windowStyle
;
2554 void wxWindow::CaptureMouse()
2556 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2558 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2560 GtkWidget
*connect_widget
= GetConnectWidget();
2561 gtk_grab_add( connect_widget
);
2562 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2564 (GDK_BUTTON_PRESS_MASK
|
2565 GDK_BUTTON_RELEASE_MASK
|
2566 GDK_POINTER_MOTION_MASK
),
2573 void wxWindow::ReleaseMouse()
2575 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2577 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2579 GtkWidget
*connect_widget
= GetConnectWidget();
2580 gtk_grab_remove( connect_widget
);
2581 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2582 g_capturing
= FALSE
;
2585 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2589 wxString
wxWindow::GetTitle() const
2591 return (wxString
&)m_windowName
;
2594 wxString
wxWindow::GetLabel() const
2599 void wxWindow::SetName( const wxString
&name
)
2601 m_windowName
= name
;
2604 wxString
wxWindow::GetName() const
2606 return (wxString
&)m_windowName
;
2609 bool wxWindow::IsShown() const
2614 bool wxWindow::IsRetained()
2619 wxWindow
*wxWindow::FindWindow( long id
)
2621 if (id
== m_windowId
) return this;
2622 wxNode
*node
= m_children
.First();
2625 wxWindow
*child
= (wxWindow
*)node
->Data();
2626 wxWindow
*res
= child
->FindWindow( id
);
2627 if (res
) return res
;
2628 node
= node
->Next();
2630 return (wxWindow
*) NULL
;
2633 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2635 if (name
== m_windowName
) return this;
2636 wxNode
*node
= m_children
.First();
2639 wxWindow
*child
= (wxWindow
*)node
->Data();
2640 wxWindow
*res
= child
->FindWindow( name
);
2641 if (res
) return res
;
2642 node
= node
->Next();
2644 return (wxWindow
*) NULL
;
2647 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2648 int range
, bool refresh
)
2650 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2652 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2654 m_hasScrolling
= TRUE
;
2656 if (orient
== wxHORIZONTAL
)
2658 float fpos
= (float)pos
;
2659 float frange
= (float)range
;
2660 float fthumb
= (float)thumbVisible
;
2661 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2662 if (fpos
< 0.0) fpos
= 0.0;
2664 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2665 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2667 SetScrollPos( orient
, pos
, refresh
);
2671 m_oldHorizontalPos
= fpos
;
2673 m_hAdjust
->lower
= 0.0;
2674 m_hAdjust
->upper
= frange
;
2675 m_hAdjust
->value
= fpos
;
2676 m_hAdjust
->step_increment
= 1.0;
2677 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2678 m_hAdjust
->page_size
= fthumb
;
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_vAdjust
->upper
) < 0.2) &&
2689 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2691 SetScrollPos( orient
, pos
, refresh
);
2695 m_oldVerticalPos
= fpos
;
2697 m_vAdjust
->lower
= 0.0;
2698 m_vAdjust
->upper
= frange
;
2699 m_vAdjust
->value
= fpos
;
2700 m_vAdjust
->step_increment
= 1.0;
2701 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2702 m_vAdjust
->page_size
= fthumb
;
2705 if (m_wxwindow
->window
)
2707 if (orient
== wxHORIZONTAL
)
2708 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2710 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2712 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2716 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2718 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2720 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2722 if (orient
== wxHORIZONTAL
)
2724 float fpos
= (float)pos
;
2725 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2726 if (fpos
< 0.0) fpos
= 0.0;
2727 m_oldHorizontalPos
= fpos
;
2729 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2730 m_hAdjust
->value
= fpos
;
2734 float fpos
= (float)pos
;
2735 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2736 if (fpos
< 0.0) fpos
= 0.0;
2737 m_oldVerticalPos
= fpos
;
2739 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2740 m_vAdjust
->value
= fpos
;
2745 if (m_wxwindow
->window
)
2747 if (orient
== wxHORIZONTAL
)
2748 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2750 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2755 int wxWindow::GetScrollThumb( int orient
) const
2757 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2759 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2761 if (orient
== wxHORIZONTAL
)
2762 return (int)(m_hAdjust
->page_size
+0.5);
2764 return (int)(m_vAdjust
->page_size
+0.5);
2767 int wxWindow::GetScrollPos( int orient
) const
2769 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2771 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2773 if (orient
== wxHORIZONTAL
)
2774 return (int)(m_hAdjust
->value
+0.5);
2776 return (int)(m_vAdjust
->value
+0.5);
2779 int wxWindow::GetScrollRange( 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
->upper
+0.5);
2788 return (int)(m_vAdjust
->upper
+0.5);
2791 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2793 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2795 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2799 GetClientSize( &cw
, &ch
);
2801 int w
= cw
- abs(dx
);
2802 int h
= ch
- abs(dy
);
2803 if ((h
< 0) || (w
< 0))
2810 if (dx
< 0) s_x
= -dx
;
2811 if (dy
< 0) s_y
= -dy
;
2814 if (dx
> 0) d_x
= dx
;
2815 if (dy
> 0) d_y
= dy
;
2819 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2820 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2823 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2824 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2827 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2828 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2829 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2830 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2832 Refresh( TRUE
, &rect
);
2835 //-------------------------------------------------------------------------------------
2837 //-------------------------------------------------------------------------------------
2839 wxLayoutConstraints
*wxWindow::GetConstraints() const
2841 return m_constraints
;
2844 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2848 UnsetConstraints(m_constraints
);
2849 delete m_constraints
;
2851 m_constraints
= constraints
;
2854 // Make sure other windows know they're part of a 'meaningful relationship'
2855 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2856 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2857 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2858 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2859 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2860 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2861 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2862 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2863 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2864 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2865 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2866 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2867 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2868 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2869 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2870 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2876 void wxWindow::SetAutoLayout( bool autoLayout
)
2878 m_autoLayout
= autoLayout
;
2881 bool wxWindow::GetAutoLayout() const
2883 return m_autoLayout
;
2886 wxSizer
*wxWindow::GetSizer() const
2888 return m_windowSizer
;
2891 void wxWindow::SetSizerParent( wxWindow
*win
)
2893 m_sizerParent
= win
;
2896 wxWindow
*wxWindow::GetSizerParent() const
2898 return m_sizerParent
;
2901 // This removes any dangling pointers to this window
2902 // in other windows' constraintsInvolvedIn lists.
2903 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2907 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2908 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2909 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2910 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2911 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2912 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2913 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2914 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2915 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2916 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2917 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2918 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2919 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2920 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2921 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2922 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2926 // Back-pointer to other windows we're involved with, so if we delete
2927 // this window, we must delete any constraints we're involved with.
2928 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2930 if (!m_constraintsInvolvedIn
)
2931 m_constraintsInvolvedIn
= new wxList
;
2932 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2933 m_constraintsInvolvedIn
->Append(otherWin
);
2936 // REMOVE back-pointer to other windows we're involved with.
2937 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2939 if (m_constraintsInvolvedIn
)
2940 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2943 // Reset any constraints that mention this window
2944 void wxWindow::DeleteRelatedConstraints()
2946 if (m_constraintsInvolvedIn
)
2948 wxNode
*node
= m_constraintsInvolvedIn
->First();
2951 wxWindow
*win
= (wxWindow
*)node
->Data();
2952 wxNode
*next
= node
->Next();
2953 wxLayoutConstraints
*constr
= win
->GetConstraints();
2955 // Reset any constraints involving this window
2958 constr
->left
.ResetIfWin((wxWindow
*)this);
2959 constr
->top
.ResetIfWin((wxWindow
*)this);
2960 constr
->right
.ResetIfWin((wxWindow
*)this);
2961 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2962 constr
->width
.ResetIfWin((wxWindow
*)this);
2963 constr
->height
.ResetIfWin((wxWindow
*)this);
2964 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2965 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2970 delete m_constraintsInvolvedIn
;
2971 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2975 void wxWindow::SetSizer(wxSizer
*sizer
)
2977 m_windowSizer
= sizer
;
2979 sizer
->SetSizerParent((wxWindow
*)this);
2986 bool wxWindow::Layout()
2988 if (GetConstraints())
2991 GetClientSize(&w
, &h
);
2992 GetConstraints()->width
.SetValue(w
);
2993 GetConstraints()->height
.SetValue(h
);
2996 // If top level (one sizer), evaluate the sizer's constraints.
3000 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3001 GetSizer()->LayoutPhase1(&noChanges
);
3002 GetSizer()->LayoutPhase2(&noChanges
);
3003 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3008 // Otherwise, evaluate child constraints
3009 ResetConstraints(); // Mark all constraints as unevaluated
3010 DoPhase(1); // Just one phase need if no sizers involved
3012 SetConstraintSizes(); // Recursively set the real window sizes
3018 // Do a phase of evaluating constraints:
3019 // the default behaviour. wxSizers may do a similar
3020 // thing, but also impose their own 'constraints'
3021 // and order the evaluation differently.
3022 bool wxWindow::LayoutPhase1(int *noChanges
)
3024 wxLayoutConstraints
*constr
= GetConstraints();
3027 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3033 bool wxWindow::LayoutPhase2(int *noChanges
)
3043 // Do a phase of evaluating child constraints
3044 bool wxWindow::DoPhase(int phase
)
3046 int noIterations
= 0;
3047 int maxIterations
= 500;
3051 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3055 wxNode
*node
= m_children
.First();
3058 wxWindow
*child
= (wxWindow
*)node
->Data();
3059 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3061 wxLayoutConstraints
*constr
= child
->GetConstraints();
3064 if (succeeded
.Member(child
))
3069 int tempNoChanges
= 0;
3070 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3071 noChanges
+= tempNoChanges
;
3074 succeeded
.Append(child
);
3079 node
= node
->Next();
3086 void wxWindow::ResetConstraints()
3088 wxLayoutConstraints
*constr
= GetConstraints();
3091 constr
->left
.SetDone(FALSE
);
3092 constr
->top
.SetDone(FALSE
);
3093 constr
->right
.SetDone(FALSE
);
3094 constr
->bottom
.SetDone(FALSE
);
3095 constr
->width
.SetDone(FALSE
);
3096 constr
->height
.SetDone(FALSE
);
3097 constr
->centreX
.SetDone(FALSE
);
3098 constr
->centreY
.SetDone(FALSE
);
3100 wxNode
*node
= m_children
.First();
3103 wxWindow
*win
= (wxWindow
*)node
->Data();
3104 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3105 win
->ResetConstraints();
3106 node
= node
->Next();
3110 // Need to distinguish between setting the 'fake' size for
3111 // windows and sizers, and setting the real values.
3112 void wxWindow::SetConstraintSizes(bool recurse
)
3114 wxLayoutConstraints
*constr
= GetConstraints();
3115 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3116 constr
->width
.GetDone() && constr
->height
.GetDone())
3118 int x
= constr
->left
.GetValue();
3119 int y
= constr
->top
.GetValue();
3120 int w
= constr
->width
.GetValue();
3121 int h
= constr
->height
.GetValue();
3123 // If we don't want to resize this window, just move it...
3124 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3125 (constr
->height
.GetRelationship() != wxAsIs
))
3127 // Calls Layout() recursively. AAAGH. How can we stop that.
3128 // Simply take Layout() out of non-top level OnSizes.
3129 SizerSetSize(x
, y
, w
, h
);
3138 char *windowClass
= this->GetClassInfo()->GetClassName();
3141 if (GetName() == "")
3142 winName
= "unnamed";
3144 winName
= GetName();
3145 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3146 (const char *)windowClass
,
3147 (const char *)winName
);
3148 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3149 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3150 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3151 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3152 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3157 wxNode
*node
= m_children
.First();
3160 wxWindow
*win
= (wxWindow
*)node
->Data();
3161 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3162 win
->SetConstraintSizes();
3163 node
= node
->Next();
3168 // This assumes that all sizers are 'on' the same
3169 // window, i.e. the parent of this window.
3170 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3172 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3173 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3177 m_sizerParent
->GetPosition(&xp
, &yp
);
3178 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3183 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3187 TransformSizerToActual(&xx
, &yy
);
3188 SetSize(xx
, yy
, w
, h
);
3191 void wxWindow::SizerMove(int x
, int y
)
3195 TransformSizerToActual(&xx
, &yy
);
3199 // Only set the size/position of the constraint (if any)
3200 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3202 wxLayoutConstraints
*constr
= GetConstraints();
3207 constr
->left
.SetValue(x
);
3208 constr
->left
.SetDone(TRUE
);
3212 constr
->top
.SetValue(y
);
3213 constr
->top
.SetDone(TRUE
);
3217 constr
->width
.SetValue(w
);
3218 constr
->width
.SetDone(TRUE
);
3222 constr
->height
.SetValue(h
);
3223 constr
->height
.SetDone(TRUE
);
3228 void wxWindow::MoveConstraint(int x
, int y
)
3230 wxLayoutConstraints
*constr
= GetConstraints();
3235 constr
->left
.SetValue(x
);
3236 constr
->left
.SetDone(TRUE
);
3240 constr
->top
.SetValue(y
);
3241 constr
->top
.SetDone(TRUE
);
3246 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3248 wxLayoutConstraints
*constr
= GetConstraints();
3251 *w
= constr
->width
.GetValue();
3252 *h
= constr
->height
.GetValue();
3258 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3260 wxLayoutConstraints
*constr
= GetConstraints();
3263 *w
= constr
->width
.GetValue();
3264 *h
= constr
->height
.GetValue();
3267 GetClientSize(w
, h
);
3270 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3272 wxLayoutConstraints
*constr
= GetConstraints();
3275 *x
= constr
->left
.GetValue();
3276 *y
= constr
->top
.GetValue();
3282 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )