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 //-----------------------------------------------------------------------------
127 extern wxList wxPendingDelete
;
128 extern wxList wxTopLevelWindows
;
129 extern bool g_blockEventsOnDrag
;
130 extern bool g_blockEventsOnScroll
;
131 static bool g_capturing
= FALSE
;
133 // hack: we need something to pass to gtk_menu_popup, so we store the time of
134 // the last click here
135 static guint32 gs_timeLastClick
= 0;
137 //-----------------------------------------------------------------------------
138 // "expose_event" (of m_wxwindow, not of m_widget)
139 //-----------------------------------------------------------------------------
141 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
143 if (!win
->HasVMT()) return;
145 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
147 gdk_event
->area
.width
,
148 gdk_event
->area
.height
);
150 if (gdk_event
->count
> 0) return;
153 printf( "OnExpose from " );
154 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
155 printf( win->GetClassInfo()->GetClassName() );
159 wxPaintEvent
event( win
->GetId() );
160 event
.SetEventObject( win
);
161 win
->GetEventHandler()->ProcessEvent( event
);
163 win
->m_updateRegion
.Clear();
166 //-----------------------------------------------------------------------------
167 // "draw" (of m_wxwindow, not of m_widget)
168 //-----------------------------------------------------------------------------
170 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
172 if (!win
->HasVMT()) return;
174 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
176 wxPaintEvent
event( win
->GetId() );
177 event
.SetEventObject( win
);
178 win
->GetEventHandler()->ProcessEvent( event
);
180 win
->m_updateRegion
.Clear();
183 //-----------------------------------------------------------------------------
185 //-----------------------------------------------------------------------------
187 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
189 if (!win
->HasVMT()) return FALSE
;
190 if (g_blockEventsOnDrag
) return FALSE
;
193 printf( "OnKeyPress from " );
194 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
195 printf( win->GetClassInfo()->GetClassName() );
200 switch (gdk_event
->keyval
)
202 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
203 case GDK_Tab
: key_code
= WXK_TAB
; break;
204 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
205 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
206 case GDK_Return
: key_code
= WXK_RETURN
; break;
207 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
208 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
209 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
210 case GDK_Delete
: key_code
= WXK_DELETE
; break;
211 case GDK_Home
: key_code
= WXK_HOME
; break;
212 case GDK_Left
: key_code
= WXK_LEFT
; break;
213 case GDK_Up
: key_code
= WXK_UP
; break;
214 case GDK_Right
: key_code
= WXK_RIGHT
; break;
215 case GDK_Down
: key_code
= WXK_DOWN
; break;
216 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
217 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
218 case GDK_Next
: key_code
= WXK_NEXT
; break;
219 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
220 case GDK_End
: key_code
= WXK_END
; break;
221 case GDK_Begin
: key_code
= WXK_HOME
; break;
222 case GDK_Select
: key_code
= WXK_SELECT
; break;
223 case GDK_Print
: key_code
= WXK_PRINT
; break;
224 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
225 case GDK_Insert
: key_code
= WXK_INSERT
; break;
226 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
227 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
228 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
229 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
230 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
231 case GDK_KP_Up
: key_code
= WXK_UP
; break;
232 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
233 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
234 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
235 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
236 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
237 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
238 case GDK_KP_End
: key_code
= WXK_END
; break;
239 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
240 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
241 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
242 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
243 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
244 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
245 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
246 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
247 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
248 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
249 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
250 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
251 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
252 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
253 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
254 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
255 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
256 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
257 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
258 case GDK_F1
: key_code
= WXK_F1
; break;
259 case GDK_F2
: key_code
= WXK_F2
; break;
260 case GDK_F3
: key_code
= WXK_F3
; break;
261 case GDK_F4
: key_code
= WXK_F4
; break;
262 case GDK_F5
: key_code
= WXK_F5
; break;
263 case GDK_F6
: key_code
= WXK_F6
; break;
264 case GDK_F7
: key_code
= WXK_F7
; break;
265 case GDK_F8
: key_code
= WXK_F8
; break;
266 case GDK_F9
: key_code
= WXK_F9
; break;
267 case GDK_F10
: key_code
= WXK_F10
; break;
268 case GDK_F11
: key_code
= WXK_F11
; break;
269 case GDK_F12
: key_code
= WXK_F12
; break;
272 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
273 key_code
= gdk_event
->keyval
;
277 if (!key_code
) return FALSE
;
279 wxKeyEvent
event( wxEVT_CHAR
);
280 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
281 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
282 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
283 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
284 event
.m_keyCode
= key_code
;
287 event
.SetEventObject( win
);
289 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
293 wxWindow
*ancestor
= win
;
296 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
299 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
300 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
303 ancestor
= ancestor
->GetParent();
309 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
310 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
316 //-----------------------------------------------------------------------------
317 // "button_press_event"
318 //-----------------------------------------------------------------------------
320 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
322 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
324 if (g_blockEventsOnDrag
) return TRUE
;
325 if (g_blockEventsOnScroll
) return TRUE
;
329 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
331 gtk_widget_grab_focus (win
->m_wxwindow
);
334 printf( "GrabFocus from " );
335 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
336 printf( win->GetClassInfo()->GetClassName() );
343 if (!win
->HasVMT()) return TRUE
;
346 printf( "OnButtonPress from " );
347 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
348 printf( win->GetClassInfo()->GetClassName() );
352 wxEventType event_type
= wxEVT_LEFT_DOWN
;
354 if (gdk_event
->button
== 1)
356 switch (gdk_event
->type
)
358 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
359 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
363 else if (gdk_event
->button
== 2)
365 switch (gdk_event
->type
)
367 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
368 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
372 else if (gdk_event
->button
== 3)
374 switch (gdk_event
->type
)
376 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
377 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
382 wxMouseEvent
event( event_type
);
383 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
384 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
385 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
386 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
387 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
388 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
389 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
391 event
.m_x
= (long)gdk_event
->x
;
392 event
.m_y
= (long)gdk_event
->y
;
394 // Some control don't have their own X window and thus cannot get
399 wxNode
*node
= win
->GetChildren().First();
402 wxWindow
*child
= (wxWindow
*)node
->Data();
404 if (child
->m_isStaticBox
)
406 // wxStaticBox is transparent in the box itself
409 int xx1
= child
->m_x
;
410 int yy1
= child
->m_y
;
411 int xx2
= child
->m_x
+ child
->m_width
;
412 int yy2
= child
->m_x
+ child
->m_height
;
415 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
417 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
419 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
421 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
424 event
.m_x
-= child
->m_x
;
425 event
.m_y
-= child
->m_y
;
432 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
433 (child
->m_x
<= event
.m_x
) &&
434 (child
->m_y
<= event
.m_y
) &&
435 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
436 (child
->m_y
+child
->m_height
>= event
.m_y
))
439 event
.m_x
-= child
->m_x
;
440 event
.m_y
-= child
->m_y
;
448 event
.SetEventObject( win
);
450 gs_timeLastClick
= gdk_event
->time
;
452 if (win
->GetEventHandler()->ProcessEvent( event
))
453 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
458 //-----------------------------------------------------------------------------
459 // "button_release_event"
460 //-----------------------------------------------------------------------------
462 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
464 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
466 if (g_blockEventsOnDrag
) return TRUE
;
467 if (g_blockEventsOnScroll
) return TRUE
;
469 if (!win
->HasVMT()) return TRUE
;
472 printf( "OnButtonRelease from " );
473 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
474 printf( win->GetClassInfo()->GetClassName() );
478 wxEventType event_type
= wxEVT_NULL
;
480 switch (gdk_event
->button
)
482 case 1: event_type
= wxEVT_LEFT_UP
; break;
483 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
484 case 3: event_type
= wxEVT_RIGHT_UP
; break;
487 wxMouseEvent
event( event_type
);
488 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
489 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
490 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
491 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
492 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
493 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
494 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
495 event
.m_x
= (long)gdk_event
->x
;
496 event
.m_y
= (long)gdk_event
->y
;
498 // Some control don't have their own X window and thus cannot get
503 wxNode
*node
= win
->GetChildren().First();
506 wxWindow
*child
= (wxWindow
*)node
->Data();
508 if (child
->m_isStaticBox
)
510 // wxStaticBox is transparent in the box itself
513 int xx1
= child
->m_x
;
514 int yy1
= child
->m_y
;
515 int xx2
= child
->m_x
+ child
->m_width
;
516 int yy2
= child
->m_x
+ child
->m_height
;
519 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
521 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
523 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
525 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
528 event
.m_x
-= child
->m_x
;
529 event
.m_y
-= child
->m_y
;
536 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
537 (child
->m_x
<= event
.m_x
) &&
538 (child
->m_y
<= event
.m_y
) &&
539 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
540 (child
->m_y
+child
->m_height
>= event
.m_y
))
543 event
.m_x
-= child
->m_x
;
544 event
.m_y
-= child
->m_y
;
552 event
.SetEventObject( win
);
554 if (win
->GetEventHandler()->ProcessEvent( event
))
555 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
560 //-----------------------------------------------------------------------------
561 // "motion_notify_event"
562 //-----------------------------------------------------------------------------
564 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
566 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
568 if (g_blockEventsOnDrag
) return TRUE
;
569 if (g_blockEventsOnScroll
) return TRUE
;
571 if (!win
->HasVMT()) return TRUE
;
574 printf( "OnMotion from " );
575 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
576 printf( win->GetClassInfo()->GetClassName() );
580 wxMouseEvent
event( wxEVT_MOTION
);
581 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
582 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
583 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
584 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
585 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
586 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
587 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
589 event
.m_x
= (long)gdk_event
->x
;
590 event
.m_y
= (long)gdk_event
->y
;
592 // Some control don't have their own X window and thus cannot get
597 wxNode
*node
= win
->GetChildren().First();
600 wxWindow
*child
= (wxWindow
*)node
->Data();
602 if (child
->m_isStaticBox
)
604 // wxStaticBox is transparent in the box itself
607 int xx1
= child
->m_x
;
608 int yy1
= child
->m_y
;
609 int xx2
= child
->m_x
+ child
->m_width
;
610 int yy2
= child
->m_x
+ child
->m_height
;
613 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
615 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
617 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
619 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
622 event
.m_x
-= child
->m_x
;
623 event
.m_y
-= child
->m_y
;
630 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
631 (child
->m_x
<= event
.m_x
) &&
632 (child
->m_y
<= event
.m_y
) &&
633 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
634 (child
->m_y
+child
->m_height
>= event
.m_y
))
637 event
.m_x
-= child
->m_x
;
638 event
.m_y
-= child
->m_y
;
646 event
.SetEventObject( win
);
648 if (win
->GetEventHandler()->ProcessEvent( event
))
649 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
654 //-----------------------------------------------------------------------------
656 //-----------------------------------------------------------------------------
658 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
660 if (g_blockEventsOnDrag
) return TRUE
;
663 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
665 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
667 printf( "SetFocus flag from " );
668 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
669 printf( win->GetClassInfo()->GetClassName() );
675 if (!win
->HasVMT()) return TRUE
;
678 printf( "OnSetFocus from " );
679 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
680 printf( win->GetClassInfo()->GetClassName() );
682 printf( WXSTRINGCAST win->GetLabel() );
686 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
687 event
.SetEventObject( win
);
689 if (win
->GetEventHandler()->ProcessEvent( event
))
690 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
695 //-----------------------------------------------------------------------------
697 //-----------------------------------------------------------------------------
699 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
701 if (g_blockEventsOnDrag
) return TRUE
;
704 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
705 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
708 if (!win
->HasVMT()) return TRUE
;
711 printf( "OnKillFocus from " );
712 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
713 printf( win->GetClassInfo()->GetClassName() );
717 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
718 event
.SetEventObject( win
);
720 if (win
->GetEventHandler()->ProcessEvent( event
))
721 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
726 //-----------------------------------------------------------------------------
727 // "enter_notify_event"
728 //-----------------------------------------------------------------------------
730 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
732 if (widget
->window
!= gdk_event
->window
) return TRUE
;
734 if (g_blockEventsOnDrag
) return TRUE
;
736 if (!win
->HasVMT()) return TRUE
;
739 printf( "OnEnter from " );
740 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
741 printf( win->GetClassInfo()->GetClassName() );
745 if ((widget
->window
) && (win
->m_cursor
))
746 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
748 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
749 event
.SetEventObject( win
);
753 GdkModifierType state
= (GdkModifierType
)0;
755 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
757 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
758 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
759 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
760 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
761 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
762 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
763 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
768 if (win
->GetEventHandler()->ProcessEvent( event
))
769 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
774 //-----------------------------------------------------------------------------
775 // "leave_notify_event"
776 //-----------------------------------------------------------------------------
778 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
780 if (widget
->window
!= gdk_event
->window
) return TRUE
;
782 if (g_blockEventsOnDrag
) return TRUE
;
784 if (!win
->HasVMT()) return TRUE
;
787 printf( "OnLeave from " );
788 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
789 printf( win->GetClassInfo()->GetClassName() );
793 if ((widget
->window
) && (win
->m_cursor
))
794 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
796 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
797 event
.SetEventObject( win
);
801 GdkModifierType state
= (GdkModifierType
)0;
803 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
805 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
806 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
807 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
808 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
809 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
810 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
811 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
816 if (win
->GetEventHandler()->ProcessEvent( event
))
817 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
822 //-----------------------------------------------------------------------------
823 // "value_changed" from m_vAdjust
824 //-----------------------------------------------------------------------------
826 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
828 if (g_blockEventsOnDrag
) return;
831 printf( "OnVScroll from " );
832 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
833 printf( win->GetClassInfo()->GetClassName() );
837 if (!win
->HasVMT()) return;
839 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
840 if (fabs(diff
) < 0.2) return;
842 wxEventType command
= wxEVT_NULL
;
844 float line_step
= win
->m_vAdjust
->step_increment
;
845 float page_step
= win
->m_vAdjust
->page_increment
;
847 if (win
->m_isScrolling
)
849 command
= wxEVT_SCROLL_THUMBTRACK
;
853 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
854 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
855 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
856 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
857 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
858 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
859 else command
= wxEVT_SCROLL_THUMBTRACK
;
862 int value
= (int)(win
->m_vAdjust
->value
+0.5);
864 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
865 event
.SetEventObject( win
);
866 win
->GetEventHandler()->ProcessEvent( event
);
869 //-----------------------------------------------------------------------------
870 // "value_changed" from m_hAdjust
871 //-----------------------------------------------------------------------------
873 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
875 if (g_blockEventsOnDrag
) return;
878 printf( "OnHScroll from " );
879 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
880 printf( win->GetClassInfo()->GetClassName() );
884 if (!win
->HasVMT()) return;
886 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
887 if (fabs(diff
) < 0.2) return;
889 wxEventType command
= wxEVT_NULL
;
891 float line_step
= win
->m_hAdjust
->step_increment
;
892 float page_step
= win
->m_hAdjust
->page_increment
;
894 if (win
->m_isScrolling
)
896 command
= wxEVT_SCROLL_THUMBTRACK
;
900 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
901 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
902 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
903 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
904 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
905 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
906 else command
= wxEVT_SCROLL_THUMBTRACK
;
909 int value
= (int)(win
->m_hAdjust
->value
+0.5);
911 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
912 event
.SetEventObject( win
);
913 win
->GetEventHandler()->ProcessEvent( event
);
916 //-----------------------------------------------------------------------------
917 // "changed" from m_vAdjust
918 //-----------------------------------------------------------------------------
920 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
922 if (g_blockEventsOnDrag
) return;
925 printf( "OnVScroll change from " );
926 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
927 printf( win->GetClassInfo()->GetClassName() );
931 if (!win
->HasVMT()) return;
933 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
934 int value
= (int)(win
->m_vAdjust
->value
+0.5);
936 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
937 event
.SetEventObject( win
);
938 win
->GetEventHandler()->ProcessEvent( event
);
941 //-----------------------------------------------------------------------------
942 // "changed" from m_hAdjust
943 //-----------------------------------------------------------------------------
945 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
947 if (g_blockEventsOnDrag
) return;
950 printf( "OnHScroll change from " );
951 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
952 printf( win->GetClassInfo()->GetClassName() );
956 if (!win
->HasVMT()) return;
958 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
959 int value
= (int)(win
->m_hAdjust
->value
+0.5);
961 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
962 event
.SetEventObject( win
);
963 win
->GetEventHandler()->ProcessEvent( event
);
966 //-----------------------------------------------------------------------------
967 // "button_press_event" from scrollbar
968 //-----------------------------------------------------------------------------
970 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
971 GdkEventButton
*WXUNUSED(gdk_event
),
974 // don't test here as we can release the mouse while being over
975 // a different window then the slider
977 // if (gdk_event->window != widget->slider) return FALSE;
979 win
->m_isScrolling
= TRUE
;
980 g_blockEventsOnScroll
= TRUE
;
985 //-----------------------------------------------------------------------------
986 // "button_release_event" from scrollbar
987 //-----------------------------------------------------------------------------
989 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
990 GdkEventButton
*WXUNUSED(gdk_event
),
994 // don't test here as we can release the mouse while being over
995 // a different window then the slider
997 // if (gdk_event->window != widget->slider) return FALSE;
999 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1001 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1002 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1004 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1006 win
->m_isScrolling
= FALSE
;
1007 g_blockEventsOnScroll
= FALSE
;
1012 //-----------------------------------------------------------------------------
1013 // InsertChild for wxWindow.
1014 //-----------------------------------------------------------------------------
1016 // Callback for wxWindow. This very strange beast has to be used because
1017 // C++ has no virtual methods in a constructor. We have to emulate a
1018 // virtual function here as wxNotebook requires a different way to insert
1019 // a child in it. I had opted for creating a wxNotebookPage window class
1020 // which would have made this superfluous (such in the MDI window system),
1021 // but no-one was listening to me...
1023 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1025 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1026 GTK_WIDGET(child
->m_widget
),
1030 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1035 //-----------------------------------------------------------------------------
1037 //-----------------------------------------------------------------------------
1039 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1041 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1042 EVT_SIZE(wxWindow::OnSize
)
1043 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1044 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1045 EVT_IDLE(wxWindow::OnIdle
)
1048 wxWindow::wxWindow()
1050 m_widget
= (GtkWidget
*) NULL
;
1051 m_wxwindow
= (GtkWidget
*) NULL
;
1052 m_parent
= (wxWindow
*) NULL
;
1053 m_children
.DeleteContents( FALSE
);
1066 m_eventHandler
= this;
1067 m_windowValidator
= (wxValidator
*) NULL
;
1071 m_cursor
= (wxCursor
*) NULL
;
1072 m_font
= *wxSWISS_FONT
;
1074 m_windowName
= "noname";
1076 m_constraints
= (wxLayoutConstraints
*) NULL
;
1077 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1078 m_windowSizer
= (wxSizer
*) NULL
;
1079 m_sizerParent
= (wxWindow
*) NULL
;
1080 m_autoLayout
= FALSE
;
1084 m_needParent
= TRUE
;
1086 m_hasScrolling
= FALSE
;
1087 m_isScrolling
= FALSE
;
1088 m_hAdjust
= (GtkAdjustment
*) NULL
;
1089 m_vAdjust
= (GtkAdjustment
*) NULL
;
1090 m_oldHorizontalPos
= 0.0;
1091 m_oldVerticalPos
= 0.0;
1096 m_dropTarget
= (wxDropTarget
*) NULL
;
1098 m_scrollGC
= (GdkGC
*) NULL
;
1099 m_widgetStyle
= (GtkStyle
*) NULL
;
1101 m_insertCallback
= wxInsertChildInWindow
;
1103 m_clientObject
= (wxClientData
*) NULL
;
1104 m_clientData
= NULL
;
1106 m_isStaticBox
= FALSE
;
1109 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1110 const wxPoint
&pos
, const wxSize
&size
,
1111 long style
, const wxString
&name
)
1113 m_insertCallback
= wxInsertChildInWindow
;
1114 Create( parent
, id
, pos
, size
, style
, name
);
1117 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1118 const wxPoint
&pos
, const wxSize
&size
,
1119 long style
, const wxString
&name
)
1123 m_needParent
= TRUE
;
1125 PreCreation( parent
, id
, pos
, size
, style
, name
);
1127 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1128 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1130 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1132 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1133 scroll_class
->scrollbar_spacing
= 0;
1135 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1137 m_oldHorizontalPos
= 0.0;
1138 m_oldVerticalPos
= 0.0;
1140 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1141 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1143 m_wxwindow
= gtk_myfixed_new();
1145 #ifdef NEW_GTK_SCROLL_CODE
1146 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1147 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1149 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1150 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1153 if (m_windowStyle
& wxRAISED_BORDER
)
1155 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1157 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1159 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1163 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1166 if (m_windowStyle
& wxTAB_TRAVERSAL
== wxTAB_TRAVERSAL
)
1167 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1169 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1171 // shut the viewport up
1172 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1173 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1175 // I _really_ don't want scrollbars in the beginning
1176 m_vAdjust
->lower
= 0.0;
1177 m_vAdjust
->upper
= 1.0;
1178 m_vAdjust
->value
= 0.0;
1179 m_vAdjust
->step_increment
= 1.0;
1180 m_vAdjust
->page_increment
= 1.0;
1181 m_vAdjust
->page_size
= 5.0;
1182 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1183 m_hAdjust
->lower
= 0.0;
1184 m_hAdjust
->upper
= 1.0;
1185 m_hAdjust
->value
= 0.0;
1186 m_hAdjust
->step_increment
= 1.0;
1187 m_hAdjust
->page_increment
= 1.0;
1188 m_hAdjust
->page_size
= 5.0;
1189 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1191 // these handlers block mouse events to any window during scrolling
1192 // such as motion events and prevent GTK and wxWindows from fighting
1193 // over where the slider should be
1195 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1196 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1198 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1199 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1201 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1202 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1204 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1205 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1207 // these handers het notified when screen updates are required either when
1208 // scrolling or when the window size (and therefore scrollbar configuration)
1211 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1212 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1213 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1214 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1216 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1217 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1218 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1219 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1221 gtk_widget_show( m_wxwindow
);
1223 if (m_parent
) m_parent
->AddChild( this );
1225 (m_parent
->m_insertCallback
)( m_parent
, this );
1234 wxWindow::~wxWindow()
1238 if (m_dropTarget
) delete m_dropTarget
;
1240 if (m_parent
) m_parent
->RemoveChild( this );
1241 if (m_widget
) Show( FALSE
);
1245 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1247 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1249 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1251 if (m_widget
) gtk_widget_destroy( m_widget
);
1253 if (m_cursor
) delete m_cursor
;
1255 DeleteRelatedConstraints();
1258 // This removes any dangling pointers to this window
1259 // in other windows' constraintsInvolvedIn lists.
1260 UnsetConstraints(m_constraints
);
1261 delete m_constraints
;
1262 m_constraints
= (wxLayoutConstraints
*) NULL
;
1266 delete m_windowSizer
;
1267 m_windowSizer
= (wxSizer
*) NULL
;
1269 // If this is a child of a sizer, remove self from parent
1270 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1272 // Just in case the window has been Closed, but
1273 // we're then deleting immediately: don't leave
1274 // dangling pointers.
1275 wxPendingDelete
.DeleteObject(this);
1277 // Just in case we've loaded a top-level window via
1278 // wxWindow::LoadNativeDialog but we weren't a dialog
1280 wxTopLevelWindows
.DeleteObject(this);
1282 if (m_windowValidator
) delete m_windowValidator
;
1284 if (m_clientObject
) delete m_clientObject
;
1287 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1288 const wxPoint
&pos
, const wxSize
&size
,
1289 long style
, const wxString
&name
)
1291 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1293 m_widget
= (GtkWidget
*) NULL
;
1294 m_wxwindow
= (GtkWidget
*) NULL
;
1297 m_children
.DeleteContents( FALSE
);
1300 if (m_width
== -1) m_width
= 20;
1302 if (m_height
== -1) m_height
= 20;
1307 if (!m_needParent
) // some reasonable defaults
1311 m_x
= (gdk_screen_width () - m_width
) / 2;
1312 if (m_x
< 10) m_x
= 10;
1316 m_y
= (gdk_screen_height () - m_height
) / 2;
1317 if (m_y
< 10) m_y
= 10;
1328 m_eventHandler
= this;
1330 m_windowId
= id
== -1 ? wxNewId() : id
;
1334 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1335 m_font
= *wxSWISS_FONT
;
1336 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1337 m_foregroundColour
= *wxBLACK
;
1338 m_windowStyle
= style
;
1339 m_windowName
= name
;
1341 m_constraints
= (wxLayoutConstraints
*) NULL
;
1342 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1343 m_windowSizer
= (wxSizer
*) NULL
;
1344 m_sizerParent
= (wxWindow
*) NULL
;
1345 m_autoLayout
= FALSE
;
1347 m_hasScrolling
= FALSE
;
1348 m_isScrolling
= FALSE
;
1349 m_hAdjust
= (GtkAdjustment
*) NULL
;
1350 m_vAdjust
= (GtkAdjustment
*) NULL
;
1351 m_oldHorizontalPos
= 0.0;
1352 m_oldVerticalPos
= 0.0;
1357 m_dropTarget
= (wxDropTarget
*) NULL
;
1359 m_windowValidator
= (wxValidator
*) NULL
;
1360 m_scrollGC
= (GdkGC
*) NULL
;
1361 m_widgetStyle
= (GtkStyle
*) NULL
;
1363 m_clientObject
= (wxClientData
*)NULL
;
1364 m_clientData
= NULL
;
1366 m_isStaticBox
= FALSE
;
1369 void wxWindow::PostCreation()
1373 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1374 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1376 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1377 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1380 ConnectWidget( GetConnectWidget() );
1382 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1384 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1386 SetCursor( *wxSTANDARD_CURSOR
);
1391 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1393 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1394 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1396 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1397 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1399 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1400 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1402 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1403 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1405 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1406 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1408 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1409 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1411 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1412 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1414 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1415 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1418 bool wxWindow::HasVMT()
1423 bool wxWindow::Close( bool force
)
1425 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1427 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1428 event
.SetEventObject(this);
1429 event
.SetForce(force
);
1431 return GetEventHandler()->ProcessEvent(event
);
1434 bool wxWindow::Destroy()
1436 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1443 bool wxWindow::DestroyChildren()
1446 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1449 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1452 if (m_children
.Member(child
)) delete node
;
1458 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1460 // are we to set fonts here ?
1463 wxPoint
wxWindow::GetClientAreaOrigin() const
1465 return wxPoint(0,0);
1468 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1470 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1472 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1478 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1480 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1481 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1483 if (m_resizing
) return; // I don't like recursions
1486 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1488 // don't set the size for children of wxNotebook, just take the values.
1496 int old_width
= m_width
;
1497 int old_height
= m_height
;
1499 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1501 if (x
!= -1) m_x
= x
;
1502 if (y
!= -1) m_y
= y
;
1503 if (width
!= -1) m_width
= width
;
1504 if (height
!= -1) m_height
= height
;
1514 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1516 if (width
== -1) m_width
= 80;
1519 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1521 if (height
== -1) m_height
= 26;
1524 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1525 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1526 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_minWidth
;
1527 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_minHeight
;
1529 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1530 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1532 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1533 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1538 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1539 event
.SetEventObject( this );
1540 GetEventHandler()->ProcessEvent( event
);
1545 void wxWindow::SetSize( int width
, int height
)
1547 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1550 void wxWindow::Move( int x
, int y
)
1552 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1555 void wxWindow::GetSize( int *width
, int *height
) const
1557 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1559 if (width
) (*width
) = m_width
;
1560 if (height
) (*height
) = m_height
;
1563 void wxWindow::SetClientSize( int width
, int height
)
1565 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1569 SetSize( width
, height
);
1576 if (!m_hasScrolling
)
1578 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1580 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1581 (m_windowStyle
& wxSUNKEN_BORDER
))
1583 dw
+= 2 * window_class
->xthickness
;
1584 dh
+= 2 * window_class
->ythickness
;
1589 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1590 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1592 #ifdef NEW_GTK_SCROLL_CODE
1593 GtkWidget
*viewport
= scroll_window
->child
;
1595 GtkWidget
*viewport
= scroll_window
->viewport
;
1598 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1600 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1601 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1603 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1604 (m_windowStyle
& wxSUNKEN_BORDER
))
1606 dw
+= 2 * viewport_class
->xthickness
;
1607 dh
+= 2 * viewport_class
->ythickness
;
1610 if (scroll_window
->vscrollbar_visible
)
1612 dw
+= vscrollbar
->allocation
.width
;
1613 dw
+= scroll_class
->scrollbar_spacing
;
1616 if (scroll_window
->hscrollbar_visible
)
1618 dh
+= hscrollbar
->allocation
.height
;
1619 dw
+= scroll_class
->scrollbar_spacing
;
1623 SetSize( width
+dw
, height
+dh
);
1627 void wxWindow::GetClientSize( int *width
, int *height
) const
1629 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1633 if (width
) (*width
) = m_width
;
1634 if (height
) (*height
) = m_height
;
1641 if (!m_hasScrolling
)
1643 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1645 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1646 (m_windowStyle
& wxSUNKEN_BORDER
))
1648 dw
+= 2 * window_class
->xthickness
;
1649 dh
+= 2 * window_class
->ythickness
;
1654 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1655 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1657 #ifdef NEW_GTK_SCROLL_CODE
1658 GtkWidget
*viewport
= scroll_window
->child
;
1660 GtkWidget
*viewport
= scroll_window
->viewport
;
1663 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1665 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1666 (m_windowStyle
& wxSUNKEN_BORDER
))
1668 dw
+= 2 * viewport_class
->xthickness
;
1669 dh
+= 2 * viewport_class
->ythickness
;
1672 if (scroll_window
->vscrollbar_visible
)
1674 // dw += vscrollbar->allocation.width;
1675 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1676 dw
+= scroll_class
->scrollbar_spacing
;
1679 if (scroll_window
->hscrollbar_visible
)
1681 // dh += hscrollbar->allocation.height;
1683 dh
+= scroll_class
->scrollbar_spacing
;
1687 if (width
) (*width
) = m_width
- dw
;
1688 if (height
) (*height
) = m_height
- dh
;
1692 void wxWindow::GetPosition( int *x
, int *y
) const
1694 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1700 void wxWindow::ClientToScreen( int *x
, int *y
)
1702 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1704 GdkWindow
*source
= (GdkWindow
*) NULL
;
1706 source
= m_wxwindow
->window
;
1708 source
= m_widget
->window
;
1712 gdk_window_get_origin( source
, &org_x
, &org_y
);
1716 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1718 org_x
+= m_widget
->allocation
.x
;
1719 org_y
+= m_widget
->allocation
.y
;
1723 wxPoint
pt(GetClientAreaOrigin());
1731 void wxWindow::ScreenToClient( int *x
, int *y
)
1733 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1735 GdkWindow
*source
= (GdkWindow
*) NULL
;
1737 source
= m_wxwindow
->window
;
1739 source
= m_widget
->window
;
1743 gdk_window_get_origin( source
, &org_x
, &org_y
);
1747 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1749 org_x
+= m_widget
->allocation
.x
;
1750 org_y
+= m_widget
->allocation
.y
;
1754 wxPoint
pt(GetClientAreaOrigin());
1762 void wxWindow::Centre( int direction
)
1764 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1773 m_parent
->GetSize( &p_w
, &p_h
);
1774 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
1775 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
1779 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
1780 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
1786 void wxWindow::Fit()
1788 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1792 wxNode
*node
= m_children
.First();
1795 wxWindow
*win
= (wxWindow
*)node
->Data();
1797 win
->GetPosition(&wx
, &wy
);
1798 win
->GetSize(&ww
, &wh
);
1799 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
1800 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
1802 node
= node
->Next();
1805 SetClientSize(maxX
+ 7, maxY
+ 14);
1808 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1810 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1818 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1820 // if (GetAutoLayout()) Layout();
1823 bool wxWindow::Show( bool show
)
1825 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
1828 gtk_widget_show( m_widget
);
1830 gtk_widget_hide( m_widget
);
1837 void wxWindow::Enable( bool enable
)
1839 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1841 m_isEnabled
= enable
;
1843 gtk_widget_set_sensitive( m_widget
, enable
);
1844 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1847 int wxWindow::GetCharHeight() const
1849 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
1851 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
1853 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1855 return font
->ascent
+ font
->descent
;
1858 int wxWindow::GetCharWidth() const
1860 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
1862 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
1864 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1866 return gdk_string_width( font
, "H" );
1869 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1870 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1872 wxFont fontToUse
= m_font
;
1873 if (theFont
) fontToUse
= *theFont
;
1875 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
1877 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1878 if (x
) (*x
) = gdk_string_width( font
, string
);
1879 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1880 if (descent
) (*descent
) = font
->descent
;
1881 if (externalLeading
) (*externalLeading
) = 0; // ??
1884 void wxWindow::MakeModal( bool modal
)
1888 // Disable all other windows
1889 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1891 wxNode
*node
= wxTopLevelWindows
.First();
1894 wxWindow
*win
= (wxWindow
*)node
->Data();
1895 if (win
!= this) win
->Enable(!modal
);
1897 node
= node
->Next();
1902 void wxWindow::SetFocus()
1904 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1906 GtkWidget
*connect_widget
= GetConnectWidget();
1909 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) && !GTK_WIDGET_HAS_FOCUS (connect_widget
) )
1911 gtk_widget_grab_focus (connect_widget
);
1916 bool wxWindow::OnClose()
1921 void wxWindow::AddChild( wxWindow
*child
)
1923 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1924 wxCHECK_RET( (child
!= NULL
), "invalid child" );
1926 m_children
.Append( child
);
1929 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
1931 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
1933 wxWindow
*oldParent
= GetParent();
1935 if (oldParent
) oldParent
->RemoveChild( this );
1937 gtk_widget_unparent( m_widget
);
1941 newParent
->AddChild( this );
1942 (newParent
->m_insertCallback
)( newParent
, this );
1948 void wxWindow::RemoveChild( wxWindow
*child
)
1950 m_children
.DeleteObject( child
);
1951 child
->m_parent
= (wxWindow
*) NULL
;
1954 void wxWindow::SetReturnCode( int retCode
)
1956 m_retCode
= retCode
;
1959 int wxWindow::GetReturnCode()
1964 void wxWindow::Raise()
1966 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1968 if (m_widget
) gdk_window_raise( m_widget
->window
);
1971 void wxWindow::Lower()
1973 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1975 if (m_widget
) gdk_window_lower( m_widget
->window
);
1978 wxEvtHandler
*wxWindow::GetEventHandler() const
1980 return m_eventHandler
;
1983 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
1985 m_eventHandler
= handler
;
1988 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
1990 handler
->SetNextHandler(GetEventHandler());
1991 SetEventHandler(handler
);
1994 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
1996 if (GetEventHandler())
1998 wxEvtHandler
*handlerA
= GetEventHandler();
1999 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2000 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2001 SetEventHandler(handlerB
);
2005 return (wxEvtHandler
*) NULL
;
2011 return (wxEvtHandler
*) NULL
;
2014 wxValidator
*wxWindow::GetValidator()
2016 return m_windowValidator
;
2019 void wxWindow::SetValidator( const wxValidator
& validator
)
2021 if (m_windowValidator
) delete m_windowValidator
;
2022 m_windowValidator
= validator
.Clone();
2023 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2026 void wxWindow::SetClientObject( wxClientData
*data
)
2028 if (m_clientObject
) delete m_clientObject
;
2029 m_clientObject
= data
;
2032 wxClientData
*wxWindow::GetClientObject()
2034 return m_clientObject
;
2037 void wxWindow::SetClientData( void *data
)
2039 m_clientData
= data
;
2042 void *wxWindow::GetClientData()
2044 return m_clientData
;
2047 bool wxWindow::IsBeingDeleted()
2052 void wxWindow::SetId( wxWindowID id
)
2057 wxWindowID
wxWindow::GetId() const
2062 void wxWindow::SetCursor( const wxCursor
&cursor
)
2064 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2068 if (cursor
== *m_cursor
) return;
2073 *m_cursor
= *wxSTANDARD_CURSOR
;
2076 if ((m_widget
) && (m_widget
->window
))
2077 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2079 if ((m_wxwindow
) && (m_wxwindow
->window
))
2080 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2083 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2085 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2087 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2091 gdk_window_clear_area( m_wxwindow
->window
,
2105 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2107 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2111 GdkRectangle gdk_rect
;
2112 gdk_rect
.x
= rect
->x
;
2113 gdk_rect
.y
= rect
->y
;
2114 gdk_rect
.width
= rect
->width
;
2115 gdk_rect
.height
= rect
->height
;
2118 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2120 gtk_widget_draw( m_widget
, &gdk_rect
);
2124 wxRegion
wxWindow::GetUpdateRegion() const
2126 return m_updateRegion
;
2129 bool wxWindow::IsExposed( int x
, int y
) const
2131 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2134 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2136 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2139 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2141 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2144 bool wxWindow::IsExposed( const wxRect
& rect
) const
2146 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2149 void wxWindow::Clear()
2151 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2153 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2156 wxColour
wxWindow::GetBackgroundColour() const
2158 return m_backgroundColour
;
2161 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2163 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2165 if (m_backgroundColour
== colour
) return;
2167 m_backgroundColour
= colour
;
2168 if (!m_backgroundColour
.Ok()) return;
2172 GdkWindow
*window
= m_wxwindow
->window
;
2173 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2174 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2175 gdk_window_clear( window
);
2178 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2179 if (sysbg
.Red() == colour
.Red() &&
2180 sysbg
.Green() == colour
.Green() &&
2181 sysbg
.Blue() == colour
.Blue())
2183 m_backgroundColour
= wxNullColour
;
2185 m_backgroundColour
= sysbg
;
2193 wxColour
wxWindow::GetForegroundColour() const
2195 return m_foregroundColour
;
2198 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2200 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2202 if (m_foregroundColour
== colour
) return;
2204 m_foregroundColour
= colour
;
2205 if (!m_foregroundColour
.Ok()) return;
2207 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2208 if (sysbg
.Red() == colour
.Red() &&
2209 sysbg
.Green() == colour
.Green() &&
2210 sysbg
.Blue() == colour
.Blue())
2212 m_backgroundColour
= wxNullColour
;
2214 m_backgroundColour
= sysbg
;
2222 GtkStyle
*wxWindow::GetWidgetStyle()
2224 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2228 gtk_widget_get_style( m_widget
) );
2230 return m_widgetStyle
;
2233 void wxWindow::SetWidgetStyle()
2235 GtkStyle
*style
= GetWidgetStyle();
2237 gdk_font_unref( style
->font
);
2238 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2240 if (m_foregroundColour
.Ok())
2242 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2243 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2244 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2245 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2248 if (m_backgroundColour
.Ok())
2250 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2251 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2252 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2253 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2254 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2255 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2256 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2257 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2258 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2262 void wxWindow::ApplyWidgetStyle()
2266 bool wxWindow::Validate()
2268 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2270 wxNode
*node
= m_children
.First();
2273 wxWindow
*child
= (wxWindow
*)node
->Data();
2274 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2278 node
= node
->Next();
2283 bool wxWindow::TransferDataToWindow()
2285 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2287 wxNode
*node
= m_children
.First();
2290 wxWindow
*child
= (wxWindow
*)node
->Data();
2291 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2292 !child
->GetValidator()->TransferToWindow() )
2294 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2297 node
= node
->Next();
2302 bool wxWindow::TransferDataFromWindow()
2304 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2306 wxNode
*node
= m_children
.First();
2309 wxWindow
*child
= (wxWindow
*)node
->Data();
2310 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2314 node
= node
->Next();
2319 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2321 m_acceleratorTable
= accel
;
2324 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2326 TransferDataToWindow();
2329 void wxWindow::InitDialog()
2331 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2333 wxInitDialogEvent
event(GetId());
2334 event
.SetEventObject( this );
2335 GetEventHandler()->ProcessEvent(event
);
2338 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2340 menu
->SetInvokingWindow( win
);
2341 wxNode
*node
= menu
->m_items
.First();
2344 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2345 if (menuitem
->IsSubMenu())
2347 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2349 node
= node
->Next();
2353 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2355 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2357 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2359 SetInvokingWindow( menu
, this );
2361 GTK_MENU(menu
->m_menu
),
2362 (GtkWidget
*)NULL
, // parent menu shell
2363 (GtkWidget
*)NULL
, // parent menu item
2364 (GtkMenuPositionFunc
)NULL
,
2365 NULL
, // client data
2366 0, // button used to activate it
2367 0//gs_timeLastClick // the time of activation
2372 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2374 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2376 GtkWidget
*dnd_widget
= GetConnectWidget();
2378 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2380 if (m_dropTarget
) delete m_dropTarget
;
2381 m_dropTarget
= dropTarget
;
2383 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2386 wxDropTarget
*wxWindow::GetDropTarget() const
2388 return m_dropTarget
;
2391 GtkWidget
* wxWindow::GetConnectWidget()
2393 GtkWidget
*connect_widget
= m_widget
;
2394 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2396 return connect_widget
;
2399 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2401 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2402 return (window
== m_widget
->window
);
2405 void wxWindow::SetFont( const wxFont
&font
)
2407 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2409 if (((wxFont
*)&font
)->Ok())
2412 m_font
= *wxSWISS_FONT
;
2414 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2415 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2416 sysbg
.Green() == m_backgroundColour
.Green() &&
2417 sysbg
.Blue() == m_backgroundColour
.Blue())
2419 m_backgroundColour
= wxNullColour
;
2421 m_backgroundColour
= sysbg
;
2429 void wxWindow::SetWindowStyleFlag( long flag
)
2431 m_windowStyle
= flag
;
2434 long wxWindow::GetWindowStyleFlag() const
2436 return m_windowStyle
;
2439 void wxWindow::CaptureMouse()
2441 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2443 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2445 GtkWidget
*connect_widget
= GetConnectWidget();
2446 gtk_grab_add( connect_widget
);
2447 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2449 (GDK_BUTTON_PRESS_MASK
|
2450 GDK_BUTTON_RELEASE_MASK
|
2451 GDK_POINTER_MOTION_MASK
),
2458 void wxWindow::ReleaseMouse()
2460 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2462 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2464 GtkWidget
*connect_widget
= GetConnectWidget();
2465 gtk_grab_remove( connect_widget
);
2466 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2467 g_capturing
= FALSE
;
2470 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2474 wxString
wxWindow::GetTitle() const
2476 return (wxString
&)m_windowName
;
2479 wxString
wxWindow::GetLabel() const
2484 void wxWindow::SetName( const wxString
&name
)
2486 m_windowName
= name
;
2489 wxString
wxWindow::GetName() const
2491 return (wxString
&)m_windowName
;
2494 bool wxWindow::IsShown() const
2499 bool wxWindow::IsRetained()
2504 wxWindow
*wxWindow::FindWindow( long id
)
2506 if (id
== m_windowId
) return this;
2507 wxNode
*node
= m_children
.First();
2510 wxWindow
*child
= (wxWindow
*)node
->Data();
2511 wxWindow
*res
= child
->FindWindow( id
);
2512 if (res
) return res
;
2513 node
= node
->Next();
2515 return (wxWindow
*) NULL
;
2518 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2520 if (name
== m_windowName
) return this;
2521 wxNode
*node
= m_children
.First();
2524 wxWindow
*child
= (wxWindow
*)node
->Data();
2525 wxWindow
*res
= child
->FindWindow( name
);
2526 if (res
) return res
;
2527 node
= node
->Next();
2529 return (wxWindow
*) NULL
;
2532 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2533 int range
, bool refresh
)
2535 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2537 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2539 m_hasScrolling
= TRUE
;
2541 if (orient
== wxHORIZONTAL
)
2543 float fpos
= (float)pos
;
2544 float frange
= (float)range
;
2545 float fthumb
= (float)thumbVisible
;
2546 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2547 if (fpos
< 0.0) fpos
= 0.0;
2549 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2550 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2552 SetScrollPos( orient
, pos
, refresh
);
2556 m_oldHorizontalPos
= fpos
;
2558 m_hAdjust
->lower
= 0.0;
2559 m_hAdjust
->upper
= frange
;
2560 m_hAdjust
->value
= fpos
;
2561 m_hAdjust
->step_increment
= 1.0;
2562 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2563 m_hAdjust
->page_size
= fthumb
;
2567 float fpos
= (float)pos
;
2568 float frange
= (float)range
;
2569 float fthumb
= (float)thumbVisible
;
2570 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2571 if (fpos
< 0.0) fpos
= 0.0;
2573 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2574 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2576 SetScrollPos( orient
, pos
, refresh
);
2580 m_oldVerticalPos
= fpos
;
2582 m_vAdjust
->lower
= 0.0;
2583 m_vAdjust
->upper
= frange
;
2584 m_vAdjust
->value
= fpos
;
2585 m_vAdjust
->step_increment
= 1.0;
2586 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2587 m_vAdjust
->page_size
= fthumb
;
2590 if (m_wxwindow
->window
)
2592 if (orient
== wxHORIZONTAL
)
2593 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2595 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2597 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2601 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2603 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2605 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2607 if (orient
== wxHORIZONTAL
)
2609 float fpos
= (float)pos
;
2610 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2611 if (fpos
< 0.0) fpos
= 0.0;
2612 m_oldHorizontalPos
= fpos
;
2614 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2615 m_hAdjust
->value
= fpos
;
2619 float fpos
= (float)pos
;
2620 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2621 if (fpos
< 0.0) fpos
= 0.0;
2622 m_oldVerticalPos
= fpos
;
2624 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2625 m_vAdjust
->value
= fpos
;
2630 if (m_wxwindow
->window
)
2632 if (orient
== wxHORIZONTAL
)
2633 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2635 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2640 int wxWindow::GetScrollThumb( int orient
) const
2642 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2644 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2646 if (orient
== wxHORIZONTAL
)
2647 return (int)(m_hAdjust
->page_size
+0.5);
2649 return (int)(m_vAdjust
->page_size
+0.5);
2652 int wxWindow::GetScrollPos( int orient
) const
2654 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2656 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2658 if (orient
== wxHORIZONTAL
)
2659 return (int)(m_hAdjust
->value
+0.5);
2661 return (int)(m_vAdjust
->value
+0.5);
2664 int wxWindow::GetScrollRange( int orient
) const
2666 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2668 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2670 if (orient
== wxHORIZONTAL
)
2671 return (int)(m_hAdjust
->upper
+0.5);
2673 return (int)(m_vAdjust
->upper
+0.5);
2676 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2678 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2680 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2684 GetClientSize( &cw
, &ch
);
2686 int w
= cw
- abs(dx
);
2687 int h
= ch
- abs(dy
);
2688 if ((h
< 0) || (w
< 0))
2695 if (dx
< 0) s_x
= -dx
;
2696 if (dy
< 0) s_y
= -dy
;
2699 if (dx
> 0) d_x
= dx
;
2700 if (dy
> 0) d_y
= dy
;
2704 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2705 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2708 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2709 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2712 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2713 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2714 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2715 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2717 Refresh( TRUE
, &rect
);
2720 //-------------------------------------------------------------------------------------
2722 //-------------------------------------------------------------------------------------
2724 wxLayoutConstraints
*wxWindow::GetConstraints() const
2726 return m_constraints
;
2729 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2733 UnsetConstraints(m_constraints
);
2734 delete m_constraints
;
2736 m_constraints
= constraints
;
2739 // Make sure other windows know they're part of a 'meaningful relationship'
2740 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2741 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2742 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2743 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2744 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2745 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2746 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2747 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2748 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2749 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2750 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2751 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2752 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2753 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2754 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2755 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2761 void wxWindow::SetAutoLayout( bool autoLayout
)
2763 m_autoLayout
= autoLayout
;
2766 bool wxWindow::GetAutoLayout() const
2768 return m_autoLayout
;
2771 wxSizer
*wxWindow::GetSizer() const
2773 return m_windowSizer
;
2776 void wxWindow::SetSizerParent( wxWindow
*win
)
2778 m_sizerParent
= win
;
2781 wxWindow
*wxWindow::GetSizerParent() const
2783 return m_sizerParent
;
2786 // This removes any dangling pointers to this window
2787 // in other windows' constraintsInvolvedIn lists.
2788 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2792 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2793 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2794 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2795 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2796 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2797 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2798 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2799 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2800 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2801 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2802 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2803 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2804 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2805 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2806 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2807 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2811 // Back-pointer to other windows we're involved with, so if we delete
2812 // this window, we must delete any constraints we're involved with.
2813 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2815 if (!m_constraintsInvolvedIn
)
2816 m_constraintsInvolvedIn
= new wxList
;
2817 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2818 m_constraintsInvolvedIn
->Append(otherWin
);
2821 // REMOVE back-pointer to other windows we're involved with.
2822 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2824 if (m_constraintsInvolvedIn
)
2825 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2828 // Reset any constraints that mention this window
2829 void wxWindow::DeleteRelatedConstraints()
2831 if (m_constraintsInvolvedIn
)
2833 wxNode
*node
= m_constraintsInvolvedIn
->First();
2836 wxWindow
*win
= (wxWindow
*)node
->Data();
2837 wxNode
*next
= node
->Next();
2838 wxLayoutConstraints
*constr
= win
->GetConstraints();
2840 // Reset any constraints involving this window
2843 constr
->left
.ResetIfWin((wxWindow
*)this);
2844 constr
->top
.ResetIfWin((wxWindow
*)this);
2845 constr
->right
.ResetIfWin((wxWindow
*)this);
2846 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2847 constr
->width
.ResetIfWin((wxWindow
*)this);
2848 constr
->height
.ResetIfWin((wxWindow
*)this);
2849 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2850 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2855 delete m_constraintsInvolvedIn
;
2856 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2860 void wxWindow::SetSizer(wxSizer
*sizer
)
2862 m_windowSizer
= sizer
;
2864 sizer
->SetSizerParent((wxWindow
*)this);
2871 bool wxWindow::Layout()
2873 if (GetConstraints())
2876 GetClientSize(&w
, &h
);
2877 GetConstraints()->width
.SetValue(w
);
2878 GetConstraints()->height
.SetValue(h
);
2881 // If top level (one sizer), evaluate the sizer's constraints.
2885 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2886 GetSizer()->LayoutPhase1(&noChanges
);
2887 GetSizer()->LayoutPhase2(&noChanges
);
2888 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2893 // Otherwise, evaluate child constraints
2894 ResetConstraints(); // Mark all constraints as unevaluated
2895 DoPhase(1); // Just one phase need if no sizers involved
2897 SetConstraintSizes(); // Recursively set the real window sizes
2903 // Do a phase of evaluating constraints:
2904 // the default behaviour. wxSizers may do a similar
2905 // thing, but also impose their own 'constraints'
2906 // and order the evaluation differently.
2907 bool wxWindow::LayoutPhase1(int *noChanges
)
2909 wxLayoutConstraints
*constr
= GetConstraints();
2912 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
2918 bool wxWindow::LayoutPhase2(int *noChanges
)
2928 // Do a phase of evaluating child constraints
2929 bool wxWindow::DoPhase(int phase
)
2931 int noIterations
= 0;
2932 int maxIterations
= 500;
2936 while ((noChanges
> 0) && (noIterations
< maxIterations
))
2940 wxNode
*node
= m_children
.First();
2943 wxWindow
*child
= (wxWindow
*)node
->Data();
2944 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
2946 wxLayoutConstraints
*constr
= child
->GetConstraints();
2949 if (succeeded
.Member(child
))
2954 int tempNoChanges
= 0;
2955 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
2956 noChanges
+= tempNoChanges
;
2959 succeeded
.Append(child
);
2964 node
= node
->Next();
2971 void wxWindow::ResetConstraints()
2973 wxLayoutConstraints
*constr
= GetConstraints();
2976 constr
->left
.SetDone(FALSE
);
2977 constr
->top
.SetDone(FALSE
);
2978 constr
->right
.SetDone(FALSE
);
2979 constr
->bottom
.SetDone(FALSE
);
2980 constr
->width
.SetDone(FALSE
);
2981 constr
->height
.SetDone(FALSE
);
2982 constr
->centreX
.SetDone(FALSE
);
2983 constr
->centreY
.SetDone(FALSE
);
2985 wxNode
*node
= m_children
.First();
2988 wxWindow
*win
= (wxWindow
*)node
->Data();
2989 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2990 win
->ResetConstraints();
2991 node
= node
->Next();
2995 // Need to distinguish between setting the 'fake' size for
2996 // windows and sizers, and setting the real values.
2997 void wxWindow::SetConstraintSizes(bool recurse
)
2999 wxLayoutConstraints
*constr
= GetConstraints();
3000 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3001 constr
->width
.GetDone() && constr
->height
.GetDone())
3003 int x
= constr
->left
.GetValue();
3004 int y
= constr
->top
.GetValue();
3005 int w
= constr
->width
.GetValue();
3006 int h
= constr
->height
.GetValue();
3008 // If we don't want to resize this window, just move it...
3009 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3010 (constr
->height
.GetRelationship() != wxAsIs
))
3012 // Calls Layout() recursively. AAAGH. How can we stop that.
3013 // Simply take Layout() out of non-top level OnSizes.
3014 SizerSetSize(x
, y
, w
, h
);
3023 char *windowClass
= this->GetClassInfo()->GetClassName();
3026 if (GetName() == "")
3027 winName
= "unnamed";
3029 winName
= GetName();
3030 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3031 (const char *)windowClass
,
3032 (const char *)winName
);
3033 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3034 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3035 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3036 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3037 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3042 wxNode
*node
= m_children
.First();
3045 wxWindow
*win
= (wxWindow
*)node
->Data();
3046 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3047 win
->SetConstraintSizes();
3048 node
= node
->Next();
3053 // This assumes that all sizers are 'on' the same
3054 // window, i.e. the parent of this window.
3055 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3057 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3058 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3062 m_sizerParent
->GetPosition(&xp
, &yp
);
3063 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3068 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3072 TransformSizerToActual(&xx
, &yy
);
3073 SetSize(xx
, yy
, w
, h
);
3076 void wxWindow::SizerMove(int x
, int y
)
3080 TransformSizerToActual(&xx
, &yy
);
3084 // Only set the size/position of the constraint (if any)
3085 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3087 wxLayoutConstraints
*constr
= GetConstraints();
3092 constr
->left
.SetValue(x
);
3093 constr
->left
.SetDone(TRUE
);
3097 constr
->top
.SetValue(y
);
3098 constr
->top
.SetDone(TRUE
);
3102 constr
->width
.SetValue(w
);
3103 constr
->width
.SetDone(TRUE
);
3107 constr
->height
.SetValue(h
);
3108 constr
->height
.SetDone(TRUE
);
3113 void wxWindow::MoveConstraint(int x
, int y
)
3115 wxLayoutConstraints
*constr
= GetConstraints();
3120 constr
->left
.SetValue(x
);
3121 constr
->left
.SetDone(TRUE
);
3125 constr
->top
.SetValue(y
);
3126 constr
->top
.SetDone(TRUE
);
3131 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3133 wxLayoutConstraints
*constr
= GetConstraints();
3136 *w
= constr
->width
.GetValue();
3137 *h
= constr
->height
.GetValue();
3143 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3145 wxLayoutConstraints
*constr
= GetConstraints();
3148 *w
= constr
->width
.GetValue();
3149 *h
= constr
->height
.GetValue();
3152 GetClientSize(w
, h
);
3155 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3157 wxLayoutConstraints
*constr
= GetConstraints();
3160 *x
= constr
->left
.GetValue();
3161 *y
= constr
->top
.GetValue();
3167 bool wxWindow::AcceptsFocus() const
3169 return IsEnabled() && IsShown();
3172 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )