1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "window.h"
17 #include "wx/window.h"
21 #include "wx/layout.h"
23 #include "wx/dialog.h"
24 #include "wx/msgdlg.h"
25 #include "wx/dcclient.h"
29 #include "wx/notebook.h"
30 #include "wx/statusbr.h"
32 #include "wx/gtk/win_gtk.h"
33 #include "gdk/gdkprivate.h"
34 #include "gdk/gdkkeysyms.h"
38 //-----------------------------------------------------------------------------
39 // documentation on internals
40 //-----------------------------------------------------------------------------
43 I have been asked several times about writing some documentation about
44 the GTK port of wxWindows, especially its internal structures. Obviously,
45 you cannot understand wxGTK without knowing a little about the GTK, but
46 some more information about what the wxWindow, which is the base class
47 for all other window classes, does seems required as well.
49 What does wxWindow do? It contains the common interface for the following
50 jobs of its descentants:
52 1) Define the rudimentary behaviour common to all window classes, such as
53 resizing, intercepting user input so as to make it possible to use these
54 events for special purposes in a derived class, window names etc.
56 2) Provide the possibility to contain and manage children, if the derived
57 class is allowed to contain children, which holds true for those window
58 classes, which do not display a native GTK widget. To name them, these
59 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
60 work classes are a special case and are handled a bit differently from
63 3) Provide the possibility to draw into a client area of a window. This,
64 too, only holds true for classes that do not display a native GTK widget
67 4) Provide the entire mechanism for scrolling widgets. This actaul inter-
68 face for this is usually in wxScrolledWidget, but the GTK implementation
71 5) A multitude of helper or extra methods for special purposes, such as
72 Drag'n'Drop, managing validators etc.
74 Normally one might expect, that one wxWindows class would always contain
75 one GTK widget. Under GTK, there is no such allround widget that has all
76 the functionality. Moreover, the GTK defines a client area as a different
77 widget from the actual widget you are handling. Last but not least some
78 special classes (e.g. wxFrame) handle different categories of widgets and
79 still have the possibility to draw something in the client area.
80 It was therefore required to write a special purpose GTK widget, that would
81 represent a client area in the sense of wxWindows capable to do the jobs
82 2), 3) and 4). I have written this class and it resides in win_gtk.c of
85 All windows must have a widget, with which they interact with other under-
86 lying GTK widget. It is this widget, e.g. that has to be resized etc and
87 thw wxWindow class has a member variable called m_widget which holds a
88 pointer to this widget. When the window class displays a GTK native widget,
89 this is the only GTK widget the class manages. When the class has a client
90 area for drawing into and for containing children it must have at least
91 one more GTK widget to handle (of the type GtkMyFixed, defined in win_gtk.c),
92 but there can be any number of widgets, handled by a class (e.g. the frame
93 class handles three). The common rule for all windows is only, that the
94 widget that interacts with the rest of GTK must be referenced in m_widget
95 and all other widgets must be children of this widget on the GTK level.
96 The top-most widget, which also represents the client area, must be in
97 the m_wxwindow field and must be of the type GtkMyFixed.
99 As I said, the window classes that display a GTK native widget only have
100 one widget, so in the case of e.g. the wxButton class m_widget holds a
101 pointer to a GtkButton widget. But windows with client areas (for drawing
102 and children) have a m_widget field that is a pointer to a GtkScrolled-
103 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
104 one is (in the GTK sense) a child of the GtkScrolledWindow.
106 If the m_wxwindow field is set, then all input to this widget is inter-
107 cepted and sent to the wxWindows class. If not, all input to the widget
108 that gets pointed to by m_widget gets intercepted and sent to the class.
112 //-----------------------------------------------------------------------------
114 //-----------------------------------------------------------------------------
116 extern wxList wxPendingDelete
;
117 extern wxList wxTopLevelWindows
;
118 extern bool g_blockEventsOnDrag
;
119 bool g_capturing
= FALSE
;
121 //-----------------------------------------------------------------------------
122 // "expose_event" (of m_wxwindow, not of m_widget)
123 //-----------------------------------------------------------------------------
125 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
127 if (!win
->HasVMT()) return;
128 if (g_blockEventsOnDrag
) return;
130 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
132 gdk_event
->area
.width
,
133 gdk_event
->area
.height
);
135 if (gdk_event
->count
> 0) return;
138 printf( "OnExpose from " );
139 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
140 printf( win->GetClassInfo()->GetClassName() );
144 wxPaintEvent
event( win
->GetId() );
145 event
.SetEventObject( win
);
146 win
->GetEventHandler()->ProcessEvent( event
);
148 win
->m_updateRegion
.Clear();
151 //-----------------------------------------------------------------------------
152 // "draw" (of m_wxwindow, not of m_widget)
153 //-----------------------------------------------------------------------------
155 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
157 if (!win
->HasVMT()) return;
158 if (g_blockEventsOnDrag
) return;
160 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
162 wxPaintEvent
event( win
->GetId() );
163 event
.SetEventObject( win
);
164 win
->GetEventHandler()->ProcessEvent( event
);
166 win
->m_updateRegion
.Clear();
169 //-----------------------------------------------------------------------------
171 //-----------------------------------------------------------------------------
173 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
175 if (!win
->HasVMT()) return FALSE
;
176 if (g_blockEventsOnDrag
) return FALSE
;
179 printf( "OnKeyPress from " );
180 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
181 printf( win->GetClassInfo()->GetClassName() );
186 switch (gdk_event
->keyval
)
188 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
189 case GDK_Tab
: key_code
= WXK_TAB
; break;
190 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
191 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
192 case GDK_Return
: key_code
= WXK_RETURN
; break;
193 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
194 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
195 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
196 case GDK_Delete
: key_code
= WXK_DELETE
; break;
197 case GDK_Home
: key_code
= WXK_HOME
; break;
198 case GDK_Left
: key_code
= WXK_LEFT
; break;
199 case GDK_Up
: key_code
= WXK_UP
; break;
200 case GDK_Right
: key_code
= WXK_RIGHT
; break;
201 case GDK_Down
: key_code
= WXK_DOWN
; break;
202 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
203 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
204 case GDK_Next
: key_code
= WXK_NEXT
; break;
205 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
206 case GDK_End
: key_code
= WXK_END
; break;
207 case GDK_Begin
: key_code
= WXK_HOME
; break;
208 case GDK_Select
: key_code
= WXK_SELECT
; break;
209 case GDK_Print
: key_code
= WXK_PRINT
; break;
210 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
211 case GDK_Insert
: key_code
= WXK_INSERT
; break;
212 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
213 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
214 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
215 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
216 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
217 case GDK_KP_Up
: key_code
= WXK_UP
; break;
218 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
219 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
220 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
221 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
222 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
223 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
224 case GDK_KP_End
: key_code
= WXK_END
; break;
225 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
226 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
227 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
228 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
229 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
230 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
231 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
232 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
233 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
234 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
235 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
236 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
237 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
238 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
239 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
240 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
241 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
242 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
243 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
244 case GDK_F1
: key_code
= WXK_F1
; break;
245 case GDK_F2
: key_code
= WXK_F2
; break;
246 case GDK_F3
: key_code
= WXK_F3
; break;
247 case GDK_F4
: key_code
= WXK_F4
; break;
248 case GDK_F5
: key_code
= WXK_F5
; break;
249 case GDK_F6
: key_code
= WXK_F6
; break;
250 case GDK_F7
: key_code
= WXK_F7
; break;
251 case GDK_F8
: key_code
= WXK_F8
; break;
252 case GDK_F9
: key_code
= WXK_F9
; break;
253 case GDK_F10
: key_code
= WXK_F10
; break;
254 case GDK_F11
: key_code
= WXK_F11
; break;
255 case GDK_F12
: key_code
= WXK_F12
; break;
258 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
259 key_code
= gdk_event
->keyval
;
263 if (!key_code
) return FALSE
;
265 wxKeyEvent
event( wxEVT_CHAR
);
266 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
267 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
268 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
269 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
270 event
.m_keyCode
= key_code
;
273 event
.SetEventObject( win
);
275 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
279 wxWindow
*ancestor
= win
;
282 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
285 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
286 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
289 ancestor
= ancestor
->GetParent();
295 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
296 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
302 //-----------------------------------------------------------------------------
303 // "button_press_event"
304 //-----------------------------------------------------------------------------
306 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
308 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
310 if (g_blockEventsOnDrag
) return TRUE
;
314 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
316 gtk_widget_grab_focus (win
->m_wxwindow
);
319 printf( "GrabFocus from " );
320 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
321 printf( win->GetClassInfo()->GetClassName() );
328 if (!win
->HasVMT()) return TRUE
;
331 printf( "OnButtonPress from " );
332 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
333 printf( win->GetClassInfo()->GetClassName() );
337 wxEventType event_type
= wxEVT_LEFT_DOWN
;
339 if (gdk_event
->button
== 1)
341 switch (gdk_event
->type
)
343 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
344 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
348 else if (gdk_event
->button
== 2)
350 switch (gdk_event
->type
)
352 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
353 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
357 else if (gdk_event
->button
== 3)
359 switch (gdk_event
->type
)
361 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
362 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
367 wxMouseEvent
event( event_type
);
368 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
369 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
370 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
371 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
372 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
373 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
374 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
376 event
.m_x
= (long)gdk_event
->x
;
377 event
.m_y
= (long)gdk_event
->y
;
379 // Some control don't have their own X window and thus cannot get
384 wxNode
*node
= win
->GetChildren()->First();
387 wxWindow
*child
= (wxWindow
*)node
->Data();
388 if ((child
->m_x
<= event
.m_x
) &&
389 (child
->m_y
<= event
.m_y
) &&
390 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
391 (child
->m_y
+child
->m_height
>= event
.m_y
))
394 event
.m_x
-= child
->m_x
;
395 event
.m_y
-= child
->m_y
;
402 event
.SetEventObject( win
);
404 if (win
->GetEventHandler()->ProcessEvent( event
))
405 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
410 //-----------------------------------------------------------------------------
411 // "button_release_event"
412 //-----------------------------------------------------------------------------
414 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
416 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
418 if (g_blockEventsOnDrag
) return TRUE
;
420 if (!win
->HasVMT()) return TRUE
;
423 printf( "OnButtonRelease from " );
424 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
425 printf( win->GetClassInfo()->GetClassName() );
429 wxEventType event_type
= wxEVT_NULL
;
431 switch (gdk_event
->button
)
433 case 1: event_type
= wxEVT_LEFT_UP
; break;
434 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
435 case 3: event_type
= wxEVT_RIGHT_UP
; break;
438 wxMouseEvent
event( event_type
);
439 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
440 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
441 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
442 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
443 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
444 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
445 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
446 event
.m_x
= (long)gdk_event
->x
;
447 event
.m_y
= (long)gdk_event
->y
;
449 // Some control don't have their own X window and thus cannot get
454 wxNode
*node
= win
->GetChildren()->First();
457 wxWindow
*child
= (wxWindow
*)node
->Data();
458 if ((child
->m_x
<= event
.m_x
) &&
459 (child
->m_y
<= event
.m_y
) &&
460 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
461 (child
->m_y
+child
->m_height
>= event
.m_y
))
464 event
.m_x
-= child
->m_x
;
465 event
.m_y
-= child
->m_y
;
472 event
.SetEventObject( win
);
474 if (win
->GetEventHandler()->ProcessEvent( event
))
475 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
480 //-----------------------------------------------------------------------------
481 // "motion_notify_event"
482 //-----------------------------------------------------------------------------
484 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
486 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
488 if (g_blockEventsOnDrag
) return TRUE
;
490 if (!win
->HasVMT()) return TRUE
;
493 printf( "OnMotion from " );
494 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
495 printf( win->GetClassInfo()->GetClassName() );
499 wxMouseEvent
event( wxEVT_MOTION
);
500 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
501 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
502 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
503 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
504 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
505 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
506 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
508 event
.m_x
= (long)gdk_event
->x
;
509 event
.m_y
= (long)gdk_event
->y
;
511 // Some control don't have their own X window and thus cannot get
516 wxNode
*node
= win
->GetChildren()->First();
519 wxWindow
*child
= (wxWindow
*)node
->Data();
520 if ((child
->m_x
<= event
.m_x
) &&
521 (child
->m_y
<= event
.m_y
) &&
522 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
523 (child
->m_y
+child
->m_height
>= event
.m_y
))
526 event
.m_x
-= child
->m_x
;
527 event
.m_y
-= child
->m_y
;
534 event
.SetEventObject( win
);
536 if (win
->GetEventHandler()->ProcessEvent( event
))
537 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
542 //-----------------------------------------------------------------------------
544 //-----------------------------------------------------------------------------
546 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
548 if (g_blockEventsOnDrag
) return TRUE
;
551 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
553 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
555 printf( "SetFocus flag from " );
556 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
557 printf( win->GetClassInfo()->GetClassName() );
563 if (!win
->HasVMT()) return TRUE
;
566 printf( "OnSetFocus from " );
567 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
568 printf( win->GetClassInfo()->GetClassName() );
570 printf( WXSTRINGCAST win->GetLabel() );
574 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
575 event
.SetEventObject( win
);
577 if (win
->GetEventHandler()->ProcessEvent( event
))
578 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
583 //-----------------------------------------------------------------------------
585 //-----------------------------------------------------------------------------
587 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
589 if (g_blockEventsOnDrag
) return TRUE
;
592 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
593 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
596 if (!win
->HasVMT()) return TRUE
;
599 printf( "OnKillFocus from " );
600 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
601 printf( win->GetClassInfo()->GetClassName() );
605 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
606 event
.SetEventObject( win
);
608 if (win
->GetEventHandler()->ProcessEvent( event
))
609 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
614 //-----------------------------------------------------------------------------
615 // "enter_notify_event"
616 //-----------------------------------------------------------------------------
618 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
620 if (widget
->window
!= gdk_event
->window
) return TRUE
;
622 if (g_blockEventsOnDrag
) return TRUE
;
624 if (!win
->HasVMT()) return TRUE
;
627 printf( "OnEnter from " );
628 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
629 printf( win->GetClassInfo()->GetClassName() );
633 if ((widget
->window
) && (win
->m_cursor
))
634 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
636 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
637 event
.SetEventObject( win
);
639 if (win
->GetEventHandler()->ProcessEvent( event
))
640 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
645 //-----------------------------------------------------------------------------
646 // "leave_notify_event"
647 //-----------------------------------------------------------------------------
649 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
651 if (widget
->window
!= gdk_event
->window
) return TRUE
;
653 if (g_blockEventsOnDrag
) return TRUE
;
655 if (!win
->HasVMT()) return TRUE
;
658 printf( "OnLeave from " );
659 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
660 printf( win->GetClassInfo()->GetClassName() );
664 if ((widget
->window
) && (win
->m_cursor
))
665 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
667 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
668 event
.SetEventObject( win
);
670 if (win
->GetEventHandler()->ProcessEvent( event
))
671 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
676 //-----------------------------------------------------------------------------
677 // "value_changed" from m_vAdjust
678 //-----------------------------------------------------------------------------
680 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
682 if (g_blockEventsOnDrag
) return;
685 printf( "OnVScroll from " );
686 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
687 printf( win->GetClassInfo()->GetClassName() );
691 if (!win
->HasVMT()) return;
693 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
694 if (fabs(diff
) < 0.2) return;
696 wxEventType command
= wxEVT_NULL
;
698 float line_step
= win
->m_vAdjust
->step_increment
;
699 float page_step
= win
->m_vAdjust
->page_increment
;
701 if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
702 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
703 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
704 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
705 else command
= wxEVT_SCROLL_THUMBTRACK
;
707 int value
= (int)(win
->m_vAdjust
->value
+0.5);
709 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
710 event
.SetEventObject( win
);
711 win
->GetEventHandler()->ProcessEvent( event
);
714 //-----------------------------------------------------------------------------
715 // "value_changed" from m_hAdjust
716 //-----------------------------------------------------------------------------
718 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
720 if (g_blockEventsOnDrag
) return;
723 printf( "OnHScroll from " );
724 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
725 printf( win->GetClassInfo()->GetClassName() );
729 if (!win
->HasVMT()) return;
731 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
732 if (fabs(diff
) < 0.2) return;
734 wxEventType command
= wxEVT_NULL
;
736 float line_step
= win
->m_hAdjust
->step_increment
;
737 float page_step
= win
->m_hAdjust
->page_increment
;
739 if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
740 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
741 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
742 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
743 else command
= wxEVT_SCROLL_THUMBTRACK
;
745 int value
= (int)(win
->m_hAdjust
->value
+0.5);
747 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
748 event
.SetEventObject( win
);
749 win
->GetEventHandler()->ProcessEvent( event
);
752 //-----------------------------------------------------------------------------
753 // "changed" from m_vAdjust
754 //-----------------------------------------------------------------------------
756 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
758 if (g_blockEventsOnDrag
) return;
761 printf( "OnVScroll change from " );
762 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
763 printf( win->GetClassInfo()->GetClassName() );
767 if (!win
->HasVMT()) return;
769 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
770 int value
= (int)(win
->m_vAdjust
->value
+0.5);
772 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
773 event
.SetEventObject( win
);
774 win
->GetEventHandler()->ProcessEvent( event
);
777 //-----------------------------------------------------------------------------
778 // "changed" from m_hAdjust
779 //-----------------------------------------------------------------------------
781 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
783 if (g_blockEventsOnDrag
) return;
786 printf( "OnHScroll change from " );
787 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
788 printf( win->GetClassInfo()->GetClassName() );
792 if (!win
->HasVMT()) return;
794 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
795 int value
= (int)(win
->m_hAdjust
->value
+0.5);
797 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
798 event
.SetEventObject( win
);
799 win
->GetEventHandler()->ProcessEvent( event
);
802 //-----------------------------------------------------------------------------
803 // "drop_data_available_event"
804 //-----------------------------------------------------------------------------
806 static void gtk_window_drop_callback( GtkWidget
*widget
, GdkEvent
*event
, wxWindow
*win
)
808 if (!win
->HasVMT()) return;
810 if (win
->GetDropTarget())
814 gdk_window_get_pointer( widget
->window
, &x
, &y
, (GdkModifierType
*) NULL
);
815 win
->GetDropTarget()->Drop( event
, x
, y
);
819 g_free (event->dropdataavailable.data);
820 g_free (event->dropdataavailable.data_type);
824 //-----------------------------------------------------------------------------
826 //-----------------------------------------------------------------------------
828 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
830 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
831 EVT_SIZE(wxWindow::OnSize
)
832 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
833 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
834 EVT_IDLE(wxWindow::OnIdle
)
839 m_widget
= (GtkWidget
*) NULL
;
840 m_wxwindow
= (GtkWidget
*) NULL
;
841 m_parent
= (wxWindow
*) NULL
;
842 m_children
.DeleteContents( FALSE
);
852 m_eventHandler
= this;
853 m_windowValidator
= (wxValidator
*) NULL
;
855 m_cursor
= (wxCursor
*) NULL
;
856 m_font
= *wxSWISS_FONT
;
858 m_windowName
= "noname";
859 m_constraints
= (wxLayoutConstraints
*) NULL
;
860 m_constraintsInvolvedIn
= (wxList
*) NULL
;
861 m_windowSizer
= (wxSizer
*) NULL
;
862 m_sizerParent
= (wxWindow
*) NULL
;
863 m_autoLayout
= FALSE
;
867 m_hasScrolling
= FALSE
;
868 m_hAdjust
= (GtkAdjustment
*) NULL
;
869 m_vAdjust
= (GtkAdjustment
*) NULL
;
870 m_oldHorizontalPos
= 0.0;
871 m_oldVerticalPos
= 0.0;
874 m_pDropTarget
= (wxDropTarget
*) NULL
;
876 m_hasOwnStyle
= FALSE
;
879 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
880 const wxPoint
&pos
, const wxSize
&size
,
881 long style
, const wxString
&name
)
887 m_cursor
= (wxCursor
*) NULL
;
889 PreCreation( parent
, id
, pos
, size
, style
, name
);
891 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
892 m_hasScrolling
= TRUE
;
894 GtkScrolledWindow
*s_window
;
895 s_window
= GTK_SCROLLED_WINDOW(m_widget
);
897 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
898 scroll_class
->scrollbar_spacing
= 0;
900 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
902 m_oldHorizontalPos
= 0.0;
903 m_oldVerticalPos
= 0.0;
905 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
906 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
908 gtk_signal_connect (GTK_OBJECT (m_hAdjust
), "value_changed",
909 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
910 gtk_signal_connect (GTK_OBJECT (m_vAdjust
), "value_changed",
911 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
913 gtk_signal_connect (GTK_OBJECT (m_hAdjust
), "changed",
914 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
915 gtk_signal_connect (GTK_OBJECT (m_vAdjust
), "changed",
916 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
918 GtkViewport
*viewport
;
919 viewport
= GTK_VIEWPORT(s_window
->viewport
);
921 if (m_windowStyle
& wxRAISED_BORDER
)
923 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
925 else if (m_windowStyle
& wxSUNKEN_BORDER
)
927 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
931 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
934 m_wxwindow
= gtk_myfixed_new();
936 if (m_wxwindow
) GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
938 if (m_windowStyle
& wxTAB_TRAVERSAL
== wxTAB_TRAVERSAL
)
939 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
941 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
943 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
945 // shut the viewport up
946 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
947 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
949 // I _really_ don't want scrollbars in the beginning
950 m_vAdjust
->lower
= 0.0;
951 m_vAdjust
->upper
= 1.0;
952 m_vAdjust
->value
= 0.0;
953 m_vAdjust
->step_increment
= 1.0;
954 m_vAdjust
->page_increment
= 1.0;
955 m_vAdjust
->page_size
= 5.0;
956 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
957 m_hAdjust
->lower
= 0.0;
958 m_hAdjust
->upper
= 1.0;
959 m_hAdjust
->value
= 0.0;
960 m_hAdjust
->step_increment
= 1.0;
961 m_hAdjust
->page_increment
= 1.0;
962 m_hAdjust
->page_size
= 5.0;
963 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
965 gtk_widget_show( m_wxwindow
);
974 wxWindow::~wxWindow(void)
978 if (m_pDropTarget
) delete m_pDropTarget
;
980 if (m_parent
) m_parent
->RemoveChild( this );
981 if (m_widget
) Show( FALSE
);
985 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
987 if (m_widget
) gtk_widget_destroy( m_widget
);
991 DeleteRelatedConstraints();
994 // This removes any dangling pointers to this window
995 // in other windows' constraintsInvolvedIn lists.
996 UnsetConstraints(m_constraints
);
997 delete m_constraints
;
998 m_constraints
= (wxLayoutConstraints
*) NULL
;
1002 delete m_windowSizer
;
1003 m_windowSizer
= (wxSizer
*) NULL
;
1005 // If this is a child of a sizer, remove self from parent
1006 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1008 // Just in case the window has been Closed, but
1009 // we're then deleting immediately: don't leave
1010 // dangling pointers.
1011 wxPendingDelete
.DeleteObject(this);
1013 // Just in case we've loaded a top-level window via
1014 // wxWindow::LoadNativeDialog but we weren't a dialog
1016 wxTopLevelWindows
.DeleteObject(this);
1018 if (m_windowValidator
) delete m_windowValidator
;
1021 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1022 const wxPoint
&pos
, const wxSize
&size
,
1023 long style
, const wxString
&name
)
1025 if (m_needParent
&& (parent
== NULL
))
1026 wxFatalError( "Need complete parent.", name
);
1028 m_widget
= (GtkWidget
*) NULL
;
1031 m_children
.DeleteContents( FALSE
);
1035 if (m_width
== -1) m_width
= 20;
1037 if (m_height
== -1) m_height
= 20;
1043 m_eventHandler
= this;
1046 if (m_cursor
== NULL
)
1047 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1048 m_font
= *wxSWISS_FONT
;
1049 m_backgroundColour
= wxWHITE
;
1050 m_foregroundColour
= wxBLACK
;
1051 m_windowStyle
= style
;
1052 m_windowName
= name
;
1053 m_constraints
= (wxLayoutConstraints
*) NULL
;
1054 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1055 m_windowSizer
= (wxSizer
*) NULL
;
1056 m_sizerParent
= (wxWindow
*) NULL
;
1057 m_autoLayout
= FALSE
;
1058 m_pDropTarget
= (wxDropTarget
*) NULL
;
1060 m_windowValidator
= (wxValidator
*) NULL
;
1061 m_hasOwnStyle
= FALSE
;
1064 void wxWindow::PostCreation(void)
1066 if (m_parent
) m_parent
->AddChild( this );
1070 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1071 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1073 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1074 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1077 ConnectWidget( GetConnectWidget() );
1079 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1083 gtk_widget_realize( m_wxwindow
);
1084 gdk_gc_set_exposures( m_wxwindow
->style
->fg_gc
[0], TRUE
);
1087 SetCursor( *wxSTANDARD_CURSOR
);
1092 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1094 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1095 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1097 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1098 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1100 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1101 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1103 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1104 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1106 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1107 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1109 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1110 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1112 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1113 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1115 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1116 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1119 bool wxWindow::HasVMT(void)
1124 bool wxWindow::Close( bool force
)
1126 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1127 event
.SetEventObject(this);
1128 event
.SetForce(force
);
1130 return GetEventHandler()->ProcessEvent(event
);
1133 bool wxWindow::Destroy(void)
1140 bool wxWindow::DestroyChildren(void)
1145 while ((node
= GetChildren()->First()) != (wxNode
*)NULL
)
1148 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1151 if (GetChildren()->Member(child
)) delete node
;
1158 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1160 // are we to set fonts here ?
1163 void wxWindow::ImplementSetSize(void)
1165 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1166 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1167 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_minWidth
;
1168 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_minHeight
;
1169 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1172 void wxWindow::ImplementSetPosition(void)
1174 if (IS_KIND_OF(this,wxFrame
) || IS_KIND_OF(this,wxDialog
))
1176 if ((m_x
!= -1) || (m_y
!= -1))
1177 gtk_widget_set_uposition( m_widget
, m_x
, m_y
);
1183 wxFAIL_MSG( "wxWindow::SetSize error.\n" );
1187 if ((m_parent
) && (m_parent
->m_wxwindow
))
1188 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y
);
1190 // Don't do anything for children of wxNotebook and wxMDIChildFrame
1193 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1195 if (m_resizing
) return; // I don't like recursions
1203 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1205 if (newX
== -1) newX
= m_x
;
1206 if (newY
== -1) newY
= m_y
;
1207 if (newW
== -1) newW
= m_width
;
1208 if (newH
== -1) newH
= m_height
;
1211 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1213 if (newW
== -1) newW
= 80;
1216 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1218 if (newH
== -1) newH
= 26;
1221 if ((m_x
!= newX
) || (m_y
!= newY
) || (!m_sizeSet
))
1225 ImplementSetPosition();
1227 if ((m_width
!= newW
) || (m_height
!= newH
) || (!m_sizeSet
))
1235 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1236 event
.SetEventObject( this );
1237 ProcessEvent( event
);
1242 void wxWindow::SetSize( int width
, int height
)
1244 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1247 void wxWindow::Move( int x
, int y
)
1249 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1252 void wxWindow::GetSize( int *width
, int *height
) const
1254 if (width
) (*width
) = m_width
;
1255 if (height
) (*height
) = m_height
;
1258 void wxWindow::SetClientSize( int width
, int height
)
1262 SetSize( width
, height
);
1269 if (!m_hasScrolling
)
1272 do we have sunken dialogs ?
1274 GtkStyleClass *window_class = m_wxwindow->style->klass;
1276 dw += 2 * window_class->xthickness;
1277 dh += 2 * window_class->ythickness;
1282 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1283 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1285 GtkWidget
*viewport
= scroll_window
->viewport
;
1286 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1288 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1289 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1291 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1292 (m_windowStyle
& wxSUNKEN_BORDER
))
1294 dw
+= 2 * viewport_class
->xthickness
;
1295 dh
+= 2 * viewport_class
->ythickness
;
1298 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1300 dw
+= vscrollbar
->allocation
.width
;
1301 dw
+= scroll_class
->scrollbar_spacing
;
1304 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1306 dh
+= hscrollbar
->allocation
.height
;
1307 dw
+= scroll_class
->scrollbar_spacing
;
1311 SetSize( width
+dw
, height
+dh
);
1315 void wxWindow::GetClientSize( int *width
, int *height
) const
1319 if (width
) (*width
) = m_width
;
1320 if (height
) (*height
) = m_height
;
1327 if (!m_hasScrolling
)
1330 do we have sunken dialogs ?
1332 GtkStyleClass *window_class = m_wxwindow->style->klass;
1334 dw += 2 * window_class->xthickness;
1335 dh += 2 * window_class->ythickness;
1340 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1341 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1343 GtkWidget
*viewport
= scroll_window
->viewport
;
1344 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1346 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1347 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1349 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1350 (m_windowStyle
& wxSUNKEN_BORDER
))
1352 dw
+= 2 * viewport_class
->xthickness
;
1353 dh
+= 2 * viewport_class
->ythickness
;
1356 if (GTK_WIDGET_VISIBLE(vscrollbar
))
1358 // dw += vscrollbar->allocation.width;
1359 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1360 dw
+= scroll_class
->scrollbar_spacing
;
1363 if (GTK_WIDGET_VISIBLE(hscrollbar
))
1365 // dh += hscrollbar->allocation.height;
1367 dh
+= scroll_class
->scrollbar_spacing
;
1371 if (width
) (*width
) = m_width
- dw
;
1372 if (height
) (*height
) = m_height
- dh
;
1376 void wxWindow::GetPosition( int *x
, int *y
) const
1382 void wxWindow::ClientToScreen( int *x
, int *y
)
1384 GdkWindow
*source
= (GdkWindow
*) NULL
;
1386 source
= m_wxwindow
->window
;
1388 source
= m_widget
->window
;
1392 gdk_window_get_origin( source
, &org_x
, &org_y
);
1396 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1398 org_x
+= m_widget
->allocation
.x
;
1399 org_y
+= m_widget
->allocation
.y
;
1407 void wxWindow::ScreenToClient( int *x
, int *y
)
1409 GdkWindow
*source
= (GdkWindow
*) NULL
;
1411 source
= m_wxwindow
->window
;
1413 source
= m_widget
->window
;
1417 gdk_window_get_origin( source
, &org_x
, &org_y
);
1421 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1423 org_x
+= m_widget
->allocation
.x
;
1424 org_y
+= m_widget
->allocation
.y
;
1432 void wxWindow::Centre( int direction
)
1434 if (IS_KIND_OF(this,wxDialog
) || IS_KIND_OF(this,wxFrame
))
1436 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (gdk_screen_width () - m_width
) / 2;
1437 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (gdk_screen_height () - m_height
) / 2;
1438 ImplementSetPosition();
1446 m_parent
->GetSize( &p_w
, &p_h
);
1447 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) m_x
= (p_w
- m_width
) / 2;
1448 if (direction
& wxVERTICAL
== wxVERTICAL
) m_y
= (p_h
- m_height
) / 2;
1449 ImplementSetPosition();
1454 void wxWindow::Fit(void)
1458 wxNode
*node
= GetChildren()->First();
1461 wxWindow
*win
= (wxWindow
*)node
->Data();
1463 win
->GetPosition(&wx
, &wy
);
1464 win
->GetSize(&ww
, &wh
);
1465 if ( wx
+ ww
> maxX
)
1467 if ( wy
+ wh
> maxY
)
1470 node
= node
->Next();
1472 SetClientSize(maxX
+ 5, maxY
+ 10);
1475 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
1483 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
1485 //if (GetAutoLayout()) Layout();
1488 bool wxWindow::Show( bool show
)
1491 gtk_widget_show( m_widget
);
1493 gtk_widget_hide( m_widget
);
1498 void wxWindow::Enable( bool enable
)
1500 m_isEnabled
= enable
;
1501 gtk_widget_set_sensitive( m_widget
, enable
);
1502 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
1505 int wxWindow::GetCharHeight(void) const
1507 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1508 return font
->ascent
+ font
->descent
;
1511 int wxWindow::GetCharWidth(void) const
1513 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
1514 return gdk_string_width( font
, "H" );
1517 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
1518 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
1520 wxFont fontToUse
= m_font
;
1521 if (theFont
) fontToUse
= *theFont
;
1523 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
1524 if (x
) (*x
) = gdk_string_width( font
, string
);
1525 if (y
) (*y
) = font
->ascent
+ font
->descent
;
1526 if (descent
) (*descent
) = font
->descent
;
1527 if (externalLeading
) (*externalLeading
) = 0; // ??
1530 void wxWindow::MakeModal( bool modal
)
1533 // Disable all other windows
1534 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
1536 wxNode
*node
= wxTopLevelWindows
.First();
1539 wxWindow
*win
= (wxWindow
*)node
->Data();
1541 win
->Enable(!modal
);
1543 node
= node
->Next();
1548 void wxWindow::SetFocus(void)
1550 GtkWidget
*connect_widget
= GetConnectWidget();
1553 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) && !GTK_WIDGET_HAS_FOCUS (connect_widget
) )
1555 gtk_widget_grab_focus (connect_widget
);
1560 bool wxWindow::OnClose(void)
1565 void wxWindow::AddChild( wxWindow
*child
)
1567 // Addchild is (often) called before the program
1568 // has left the parents constructor so that no
1569 // virtual tables work yet. The approach below
1570 // practically imitates virtual tables, i.e. it
1571 // implements a different AddChild() behaviour
1572 // for wxFrame, wxDialog, wxWindow and
1573 // wxMDIParentFrame.
1575 // wxFrame and wxDialog as children aren't placed into the parents
1577 if (( IS_KIND_OF(child
,wxFrame
) || IS_KIND_OF(child
,wxDialog
) ) &&
1578 (!IS_KIND_OF(child
,wxMDIChildFrame
)))
1580 m_children
.Append( child
);
1582 if ((child
->m_x
!= -1) && (child
->m_y
!= -1))
1583 gtk_widget_set_uposition( child
->m_widget
, child
->m_x
, child
->m_y
);
1588 // In the case of an wxMDIChildFrame descendant, we use the
1589 // client windows's AddChild()
1591 if (IS_KIND_OF(this,wxMDIParentFrame
))
1593 if (IS_KIND_OF(child
,wxMDIChildFrame
))
1595 wxMDIClientWindow
*client
= ((wxMDIParentFrame
*)this)->GetClientWindow();
1598 client
->AddChild( child
);
1604 // wxNotebook is very special, so it has a private AddChild()
1606 if (IS_KIND_OF(this,wxNotebook
))
1608 wxNotebook
*tab
= (wxNotebook
*)this;
1609 tab
->AddChild( child
);
1613 // wxFrame has a private AddChild
1615 if (IS_KIND_OF(this,wxFrame
) && !IS_KIND_OF(this,wxMDIChildFrame
))
1617 wxFrame
*frame
= (wxFrame
*)this;
1618 frame
->AddChild( child
);
1624 m_children
.Append( child
);
1625 if (m_wxwindow
) gtk_myfixed_put( GTK_MYFIXED(m_wxwindow
), child
->m_widget
,
1626 child
->m_x
, child
->m_y
);
1628 gtk_widget_set_usize( child
->m_widget
, child
->m_width
, child
->m_height
);
1631 wxList
*wxWindow::GetChildren(void)
1633 return (&m_children
);
1636 void wxWindow::RemoveChild( wxWindow
*child
)
1639 GetChildren()->DeleteObject( child
);
1640 child
->m_parent
= (wxWindow
*) NULL
;
1643 void wxWindow::SetReturnCode( int retCode
)
1645 m_retCode
= retCode
;
1648 int wxWindow::GetReturnCode(void)
1653 void wxWindow::Raise(void)
1655 if (m_widget
) gdk_window_raise( m_widget
->window
);
1658 void wxWindow::Lower(void)
1660 if (m_widget
) gdk_window_lower( m_widget
->window
);
1663 wxEvtHandler
*wxWindow::GetEventHandler(void)
1665 return m_eventHandler
;
1668 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
1670 m_eventHandler
= handler
;
1673 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
1675 handler
->SetNextHandler(GetEventHandler());
1676 SetEventHandler(handler
);
1679 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
1681 if ( GetEventHandler() )
1683 wxEvtHandler
*handlerA
= GetEventHandler();
1684 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
1685 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
1686 SetEventHandler(handlerB
);
1687 if ( deleteHandler
)
1690 return (wxEvtHandler
*) NULL
;
1696 return (wxEvtHandler
*) NULL
;
1699 wxValidator
*wxWindow::GetValidator(void)
1701 return m_windowValidator
;
1704 void wxWindow::SetValidator( const wxValidator
& validator
)
1706 if (m_windowValidator
) delete m_windowValidator
;
1707 m_windowValidator
= validator
.Clone();
1708 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
1711 bool wxWindow::IsBeingDeleted(void)
1716 void wxWindow::SetId( wxWindowID id
)
1721 wxWindowID
wxWindow::GetId(void)
1726 void wxWindow::SetCursor( const wxCursor
&cursor
)
1728 if (m_cursor
== NULL
)
1730 wxFAIL_MSG( "wxWindow::SetCursor m_cursor == NULL" );
1731 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1736 if (*((wxCursor
*)&cursor
) == m_cursor
) return;
1741 *m_cursor
= *wxSTANDARD_CURSOR
;
1744 if ((m_widget
) && (m_widget
->window
))
1745 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
1747 if ((m_wxwindow
) && (m_wxwindow
->window
))
1748 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
1751 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
1753 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
1756 gdk_window_clear_area( m_wxwindow
->window
,
1770 GetClientSize( &w
, &h
);
1772 GdkRectangle gdk_rect
;
1776 gdk_rect
.height
= h
;
1777 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1782 GdkRectangle gdk_rect
;
1783 gdk_rect
.x
= rect
->x
;
1784 gdk_rect
.y
= rect
->y
;
1785 gdk_rect
.width
= rect
->width
;
1786 gdk_rect
.height
= rect
->height
;
1789 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
1791 gtk_widget_draw( m_widget
, &gdk_rect
);
1795 wxRegion
wxWindow::GetUpdateRegion() const
1797 return m_updateRegion
;
1800 bool wxWindow::IsExposed( int x
, int y
) const
1802 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
1805 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
1807 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
1810 bool wxWindow::IsExposed( const wxPoint
& pt
) const
1812 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
1815 bool wxWindow::IsExposed( const wxRect
& rect
) const
1817 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
1820 void wxWindow::Clear(void)
1822 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
1825 wxColour
wxWindow::GetBackgroundColour(void) const
1827 return m_backgroundColour
;
1830 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
1832 m_backgroundColour
= colour
;
1835 m_backgroundColour
.CalcPixel( m_wxwindow
->style
->colormap
);
1836 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
1837 gdk_window_clear( m_wxwindow
->window
);
1842 wxColour
wxWindow::GetForegroundColour(void) const
1844 return m_foregroundColour
;
1847 void wxWindow::SetForegroundColour( const wxColour
&colour
)
1849 m_foregroundColour
= colour
;
1852 bool wxWindow::Validate(void)
1854 wxNode
*node
= GetChildren()->First();
1857 wxWindow
*child
= (wxWindow
*)node
->Data();
1858 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
1860 node
= node
->Next();
1865 bool wxWindow::TransferDataToWindow(void)
1867 wxNode
*node
= GetChildren()->First();
1870 wxWindow
*child
= (wxWindow
*)node
->Data();
1871 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
1872 !child
->GetValidator()->TransferToWindow() )
1874 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
1877 node
= node
->Next();
1882 bool wxWindow::TransferDataFromWindow(void)
1884 wxNode
*node
= GetChildren()->First();
1887 wxWindow
*child
= (wxWindow
*)node
->Data();
1888 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
1890 node
= node
->Next();
1895 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
1897 m_acceleratorTable
= accel
;
1900 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
1902 TransferDataToWindow();
1905 void wxWindow::InitDialog(void)
1907 wxInitDialogEvent
event(GetId());
1908 event
.SetEventObject( this );
1909 GetEventHandler()->ProcessEvent(event
);
1912 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
1914 menu
->SetInvokingWindow( win
);
1915 wxNode
*node
= menu
->m_items
.First();
1918 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
1919 if (menuitem
->IsSubMenu())
1920 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
1921 node
= node
->Next();
1925 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
1927 SetInvokingWindow( menu
, this );
1928 gtk_menu_popup( GTK_MENU(menu
->m_menu
), (GtkWidget
*) NULL
, (GtkWidget
*) NULL
, (GtkMenuPositionFunc
) NULL
, NULL
, 0, 0 );
1932 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
1934 GtkWidget
*dnd_widget
= GetConnectWidget();
1936 DisconnectDnDWidget( dnd_widget
);
1938 if (m_pDropTarget
) delete m_pDropTarget
;
1939 m_pDropTarget
= dropTarget
;
1941 ConnectDnDWidget( dnd_widget
);
1944 wxDropTarget
*wxWindow::GetDropTarget() const
1946 return m_pDropTarget
;
1949 void wxWindow::ConnectDnDWidget( GtkWidget
*widget
)
1951 if (!m_pDropTarget
) return;
1953 m_pDropTarget
->RegisterWidget( widget
);
1955 gtk_signal_connect( GTK_OBJECT(widget
), "drop_data_available_event",
1956 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
1959 void wxWindow::DisconnectDnDWidget( GtkWidget
*widget
)
1961 if (!m_pDropTarget
) return;
1963 gtk_signal_disconnect_by_func( GTK_OBJECT(widget
),
1964 GTK_SIGNAL_FUNC(gtk_window_drop_callback
), (gpointer
)this );
1966 m_pDropTarget
->UnregisterWidget( widget
);
1969 GtkWidget
* wxWindow::GetConnectWidget(void)
1971 GtkWidget
*connect_widget
= m_widget
;
1972 if (m_wxwindow
) connect_widget
= m_wxwindow
;
1974 return connect_widget
;
1977 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
1979 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
1980 return (window
== m_widget
->window
);
1983 void wxWindow::SetFont( const wxFont
&font
)
1985 if (((wxFont
*)&font
)->Ok())
1988 m_font
= *wxSWISS_FONT
;
1990 GtkStyle
*style
= (GtkStyle
*) NULL
;
1993 m_hasOwnStyle
= TRUE
;
1994 style
= gtk_style_copy( gtk_widget_get_style( m_widget
) );
1998 style
= gtk_widget_get_style( m_widget
);
2001 gdk_font_unref( style
->font
);
2002 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2004 gtk_widget_set_style( m_widget
, style
);
2007 wxFont
*wxWindow::GetFont(void)
2012 void wxWindow::SetWindowStyleFlag( long flag
)
2014 m_windowStyle
= flag
;
2017 long wxWindow::GetWindowStyleFlag(void) const
2019 return m_windowStyle
;
2022 void wxWindow::CaptureMouse(void)
2024 GtkWidget
*connect_widget
= GetConnectWidget();
2025 gtk_grab_add( connect_widget
);
2026 gdk_pointer_grab ( connect_widget
->window
, FALSE
,
2028 (GDK_BUTTON_PRESS_MASK
|
2029 GDK_BUTTON_RELEASE_MASK
|
2030 GDK_POINTER_MOTION_MASK
),
2031 (GdkWindow
*) NULL
, (GdkCursor
*) NULL
, GDK_CURRENT_TIME
);
2035 void wxWindow::ReleaseMouse(void)
2037 GtkWidget
*connect_widget
= GetConnectWidget();
2038 gtk_grab_remove( connect_widget
);
2039 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2040 g_capturing
= FALSE
;
2043 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2047 wxString
wxWindow::GetTitle(void) const
2049 return (wxString
&)m_windowName
;
2052 wxString
wxWindow::GetLabel(void) const
2057 void wxWindow::SetName( const wxString
&name
)
2059 m_windowName
= name
;
2062 wxString
wxWindow::GetName(void) const
2064 return (wxString
&)m_windowName
;
2067 bool wxWindow::IsShown(void) const
2072 bool wxWindow::IsRetained(void)
2077 wxWindow
*wxWindow::FindWindow( long id
)
2079 if (id
== m_windowId
) return this;
2080 wxNode
*node
= m_children
.First();
2083 wxWindow
*child
= (wxWindow
*)node
->Data();
2084 wxWindow
*res
= child
->FindWindow( id
);
2085 if (res
) return res
;
2086 node
= node
->Next();
2088 return (wxWindow
*) NULL
;
2091 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2093 if (name
== m_windowName
) return this;
2094 wxNode
*node
= m_children
.First();
2097 wxWindow
*child
= (wxWindow
*)node
->Data();
2098 wxWindow
*res
= child
->FindWindow( name
);
2099 if (res
) return res
;
2100 node
= node
->Next();
2102 return (wxWindow
*) NULL
;
2105 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2106 int range
, bool WXUNUSED(refresh
) )
2108 if (!m_wxwindow
) return;
2110 if (orient
== wxHORIZONTAL
)
2112 float fpos
= (float)pos
;
2113 m_oldHorizontalPos
= fpos
;
2114 float frange
= (float)range
;
2115 float fthumb
= (float)thumbVisible
;
2117 if ((fabs(fpos
-m_hAdjust
->value
) < 0.2) &&
2118 (fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2119 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2122 m_hAdjust
->lower
= 0.0;
2123 m_hAdjust
->upper
= frange
;
2124 m_hAdjust
->value
= fpos
;
2125 m_hAdjust
->step_increment
= 1.0;
2126 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
-2,0));
2127 m_hAdjust
->page_size
= fthumb
;
2131 float fpos
= (float)pos
;
2132 m_oldVerticalPos
= fpos
;
2133 float frange
= (float)range
;
2134 float fthumb
= (float)thumbVisible
;
2136 if ((fabs(fpos
-m_vAdjust
->value
) < 0.2) &&
2137 (fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2138 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2141 m_vAdjust
->lower
= 0.0;
2142 m_vAdjust
->upper
= frange
;
2143 m_vAdjust
->value
= fpos
;
2144 m_vAdjust
->step_increment
= 1.0;
2145 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
-2,0));
2146 m_vAdjust
->page_size
= fthumb
;
2149 if (m_wxwindow
->window
)
2151 if (orient
== wxHORIZONTAL
)
2152 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2154 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2156 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2160 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2162 if (!m_wxwindow
) return;
2164 if (orient
== wxHORIZONTAL
)
2166 float fpos
= (float)pos
;
2167 m_oldHorizontalPos
= fpos
;
2169 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2170 m_hAdjust
->value
= fpos
;
2174 float fpos
= (float)pos
;
2175 m_oldVerticalPos
= fpos
;
2176 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2177 m_vAdjust
->value
= fpos
;
2180 if (m_wxwindow
->window
)
2182 if (orient
== wxHORIZONTAL
)
2183 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2185 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2189 int wxWindow::GetScrollThumb( int orient
) const
2191 if (!m_wxwindow
) return 0;
2193 if (orient
== wxHORIZONTAL
)
2194 return (int)(m_hAdjust
->page_size
+0.5);
2196 return (int)(m_vAdjust
->page_size
+0.5);
2199 int wxWindow::GetScrollPos( int orient
) const
2201 if (!m_wxwindow
) return 0;
2203 if (orient
== wxHORIZONTAL
)
2204 return (int)(m_hAdjust
->value
+0.5);
2206 return (int)(m_vAdjust
->value
+0.5);
2209 int wxWindow::GetScrollRange( int orient
) const
2211 if (!m_wxwindow
) return 0;
2213 if (orient
== wxHORIZONTAL
)
2214 return (int)(m_hAdjust
->upper
+0.5);
2216 return (int)(m_vAdjust
->upper
+0.5);
2219 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2221 if (!m_wxwindow
) return;
2224 bool refresh = FALSE;
2226 if ((m_drawingOffsetX == 0) && (m_drawingOffsetY == 0))
2228 m_drawingOffsetX = -16000;
2229 m_drawingOffsetY = -16000;
2234 m_drawingOffsetX += dx;
2235 m_drawingOffsetY += dy;
2238 // printf( "X: %d Y: %d \n", (int)m_drawingOffsetX, (int)m_drawingOffsetY );
2240 gtk_myfixed_set_offset( GTK_MYFIXED(m_wxwindow), m_drawingOffsetX, m_drawingOffsetY );
2242 if (refresh) Refresh();
2244 The code here is very nifty, but it doesn't work with
2245 overlapping windows...
2250 GetClientSize( &cw
, &ch
);
2252 int w
= cw
- abs(dx
);
2253 int h
= ch
- abs(dy
);
2254 if ((h
< 0) || (w
< 0))
2261 if (dx
< 0) s_x
= -dx
;
2262 if (dy
< 0) s_y
= -dy
;
2265 if (dx
> 0) d_x
= dx
;
2266 if (dy
> 0) d_y
= dy
;
2267 gdk_window_copy_area( m_wxwindow
->window
, m_wxwindow
->style
->fg_gc
[0], d_x
, d_y
,
2268 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
2271 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
2272 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
2273 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
2274 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
2276 Refresh( TRUE
, &rect
);
2279 //-------------------------------------------------------------------------------------
2281 //-------------------------------------------------------------------------------------
2283 wxLayoutConstraints
*wxWindow::GetConstraints(void) const
2285 return m_constraints
;
2288 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
2292 UnsetConstraints(m_constraints
);
2293 delete m_constraints
;
2295 m_constraints
= constraints
;
2298 // Make sure other windows know they're part of a 'meaningful relationship'
2299 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
2300 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2301 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
2302 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2303 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
2304 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2305 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
2306 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2307 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
2308 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2309 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
2310 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2311 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
2312 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2313 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
2314 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
2320 void wxWindow::SetAutoLayout( bool autoLayout
)
2322 m_autoLayout
= autoLayout
;
2325 bool wxWindow::GetAutoLayout(void) const
2327 return m_autoLayout
;
2330 wxSizer
*wxWindow::GetSizer(void) const
2332 return m_windowSizer
;
2335 void wxWindow::SetSizerParent( wxWindow
*win
)
2337 m_sizerParent
= win
;
2340 wxWindow
*wxWindow::GetSizerParent(void) const
2342 return m_sizerParent
;
2345 // This removes any dangling pointers to this window
2346 // in other windows' constraintsInvolvedIn lists.
2347 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
2351 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2352 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2353 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
2354 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2355 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
2356 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2357 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
2358 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2359 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
2360 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2361 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
2362 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2363 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
2364 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2365 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
2366 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
2370 // Back-pointer to other windows we're involved with, so if we delete
2371 // this window, we must delete any constraints we're involved with.
2372 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
2374 if (!m_constraintsInvolvedIn
)
2375 m_constraintsInvolvedIn
= new wxList
;
2376 if (!m_constraintsInvolvedIn
->Member(otherWin
))
2377 m_constraintsInvolvedIn
->Append(otherWin
);
2380 // REMOVE back-pointer to other windows we're involved with.
2381 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
2383 if (m_constraintsInvolvedIn
)
2384 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
2387 // Reset any constraints that mention this window
2388 void wxWindow::DeleteRelatedConstraints(void)
2390 if (m_constraintsInvolvedIn
)
2392 wxNode
*node
= m_constraintsInvolvedIn
->First();
2395 wxWindow
*win
= (wxWindow
*)node
->Data();
2396 wxNode
*next
= node
->Next();
2397 wxLayoutConstraints
*constr
= win
->GetConstraints();
2399 // Reset any constraints involving this window
2402 constr
->left
.ResetIfWin((wxWindow
*)this);
2403 constr
->top
.ResetIfWin((wxWindow
*)this);
2404 constr
->right
.ResetIfWin((wxWindow
*)this);
2405 constr
->bottom
.ResetIfWin((wxWindow
*)this);
2406 constr
->width
.ResetIfWin((wxWindow
*)this);
2407 constr
->height
.ResetIfWin((wxWindow
*)this);
2408 constr
->centreX
.ResetIfWin((wxWindow
*)this);
2409 constr
->centreY
.ResetIfWin((wxWindow
*)this);
2414 delete m_constraintsInvolvedIn
;
2415 m_constraintsInvolvedIn
= (wxList
*) NULL
;
2419 void wxWindow::SetSizer(wxSizer
*sizer
)
2421 m_windowSizer
= sizer
;
2423 sizer
->SetSizerParent((wxWindow
*)this);
2430 bool wxWindow::Layout(void)
2432 if (GetConstraints())
2435 GetClientSize(&w
, &h
);
2436 GetConstraints()->width
.SetValue(w
);
2437 GetConstraints()->height
.SetValue(h
);
2440 // If top level (one sizer), evaluate the sizer's constraints.
2444 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
2445 GetSizer()->LayoutPhase1(&noChanges
);
2446 GetSizer()->LayoutPhase2(&noChanges
);
2447 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
2452 // Otherwise, evaluate child constraints
2453 ResetConstraints(); // Mark all constraints as unevaluated
2454 DoPhase(1); // Just one phase need if no sizers involved
2456 SetConstraintSizes(); // Recursively set the real window sizes
2462 // Do a phase of evaluating constraints:
2463 // the default behaviour. wxSizers may do a similar
2464 // thing, but also impose their own 'constraints'
2465 // and order the evaluation differently.
2466 bool wxWindow::LayoutPhase1(int *noChanges
)
2468 wxLayoutConstraints
*constr
= GetConstraints();
2471 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
2477 bool wxWindow::LayoutPhase2(int *noChanges
)
2487 // Do a phase of evaluating child constraints
2488 bool wxWindow::DoPhase(int phase
)
2490 int noIterations
= 0;
2491 int maxIterations
= 500;
2495 while ((noChanges
> 0) && (noIterations
< maxIterations
))
2499 wxNode
*node
= GetChildren()->First();
2502 wxWindow
*child
= (wxWindow
*)node
->Data();
2503 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
2505 wxLayoutConstraints
*constr
= child
->GetConstraints();
2508 if (succeeded
.Member(child
))
2513 int tempNoChanges
= 0;
2514 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
2515 noChanges
+= tempNoChanges
;
2518 succeeded
.Append(child
);
2523 node
= node
->Next();
2530 void wxWindow::ResetConstraints(void)
2532 wxLayoutConstraints
*constr
= GetConstraints();
2535 constr
->left
.SetDone(FALSE
);
2536 constr
->top
.SetDone(FALSE
);
2537 constr
->right
.SetDone(FALSE
);
2538 constr
->bottom
.SetDone(FALSE
);
2539 constr
->width
.SetDone(FALSE
);
2540 constr
->height
.SetDone(FALSE
);
2541 constr
->centreX
.SetDone(FALSE
);
2542 constr
->centreY
.SetDone(FALSE
);
2544 wxNode
*node
= GetChildren()->First();
2547 wxWindow
*win
= (wxWindow
*)node
->Data();
2548 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2549 win
->ResetConstraints();
2550 node
= node
->Next();
2554 // Need to distinguish between setting the 'fake' size for
2555 // windows and sizers, and setting the real values.
2556 void wxWindow::SetConstraintSizes(bool recurse
)
2558 wxLayoutConstraints
*constr
= GetConstraints();
2559 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
2560 constr
->width
.GetDone() && constr
->height
.GetDone())
2562 int x
= constr
->left
.GetValue();
2563 int y
= constr
->top
.GetValue();
2564 int w
= constr
->width
.GetValue();
2565 int h
= constr
->height
.GetValue();
2567 // If we don't want to resize this window, just move it...
2568 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
2569 (constr
->height
.GetRelationship() != wxAsIs
))
2571 // Calls Layout() recursively. AAAGH. How can we stop that.
2572 // Simply take Layout() out of non-top level OnSizes.
2573 SizerSetSize(x
, y
, w
, h
);
2582 char *windowClass
= this->GetClassInfo()->GetClassName();
2585 if (GetName() == "")
2586 winName
= _("unnamed");
2588 winName
= GetName();
2589 wxDebugMsg(_("Constraint(s) not satisfied for window of type %s, name %s:\n"), (const char *)windowClass
, (const char *)winName
);
2590 if (!constr
->left
.GetDone())
2591 wxDebugMsg(_(" unsatisfied 'left' constraint.\n"));
2592 if (!constr
->right
.GetDone())
2593 wxDebugMsg(_(" unsatisfied 'right' constraint.\n"));
2594 if (!constr
->width
.GetDone())
2595 wxDebugMsg(_(" unsatisfied 'width' constraint.\n"));
2596 if (!constr
->height
.GetDone())
2597 wxDebugMsg(_(" unsatisfied 'height' constraint.\n"));
2598 wxDebugMsg(_("Please check constraints: try adding AsIs() constraints.\n"));
2603 wxNode
*node
= GetChildren()->First();
2606 wxWindow
*win
= (wxWindow
*)node
->Data();
2607 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
2608 win
->SetConstraintSizes();
2609 node
= node
->Next();
2614 // This assumes that all sizers are 'on' the same
2615 // window, i.e. the parent of this window.
2616 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
2618 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
2619 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
2623 m_sizerParent
->GetPosition(&xp
, &yp
);
2624 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
2629 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
2633 TransformSizerToActual(&xx
, &yy
);
2634 SetSize(xx
, yy
, w
, h
);
2637 void wxWindow::SizerMove(int x
, int y
)
2641 TransformSizerToActual(&xx
, &yy
);
2645 // Only set the size/position of the constraint (if any)
2646 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
2648 wxLayoutConstraints
*constr
= GetConstraints();
2653 constr
->left
.SetValue(x
);
2654 constr
->left
.SetDone(TRUE
);
2658 constr
->top
.SetValue(y
);
2659 constr
->top
.SetDone(TRUE
);
2663 constr
->width
.SetValue(w
);
2664 constr
->width
.SetDone(TRUE
);
2668 constr
->height
.SetValue(h
);
2669 constr
->height
.SetDone(TRUE
);
2674 void wxWindow::MoveConstraint(int x
, int y
)
2676 wxLayoutConstraints
*constr
= GetConstraints();
2681 constr
->left
.SetValue(x
);
2682 constr
->left
.SetDone(TRUE
);
2686 constr
->top
.SetValue(y
);
2687 constr
->top
.SetDone(TRUE
);
2692 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
2694 wxLayoutConstraints
*constr
= GetConstraints();
2697 *w
= constr
->width
.GetValue();
2698 *h
= constr
->height
.GetValue();
2704 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
2706 wxLayoutConstraints
*constr
= GetConstraints();
2709 *w
= constr
->width
.GetValue();
2710 *h
= constr
->height
.GetValue();
2713 GetClientSize(w
, h
);
2716 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
2718 wxLayoutConstraints
*constr
= GetConstraints();
2721 *x
= constr
->left
.GetValue();
2722 *y
= constr
->top
.GetValue();
2728 bool wxWindow::AcceptsFocus() const
2730 return IsEnabled() && IsShown();
2733 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
) )