1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
12 #pragma implementation "window.h"
16 #include "wx/window.h"
20 #include "wx/layout.h"
22 #include "wx/dialog.h"
23 #include "wx/msgdlg.h"
24 #if wxUSE_DRAG_AND_DROP
28 #include "wx/statusbr.h"
30 #include "wx/settings.h"
37 #include "gdk/gdkprivate.h"
38 #include "gdk/gdkkeysyms.h"
39 #include "wx/gtk/win_gtk.h"
41 //-----------------------------------------------------------------------------
42 // documentation on internals
43 //-----------------------------------------------------------------------------
46 I have been asked several times about writing some documentation about
47 the GTK port of wxWindows, especially its internal structures. Obviously,
48 you cannot understand wxGTK without knowing a little about the GTK, but
49 some more information about what the wxWindow, which is the base class
50 for all other window classes, does seems required as well.
52 What does wxWindow do? It contains the common interface for the following
53 jobs of its descendants:
55 1) Define the rudimentary behaviour common to all window classes, such as
56 resizing, intercepting user input (so as to make it possible to use these
57 events for special purposes in a derived class), window names etc.
59 2) Provide the possibility to contain and manage children, if the derived
60 class is allowed to contain children, which holds true for those window
61 classes which do not display a native GTK widget. To name them, these
62 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
63 work classes are a special case and are handled a bit differently from
64 the rest. The same holds true for the wxNotebook class.
66 3) Provide the possibility to draw into a client area of a window. This,
67 too, only holds true for classes that do not display a native GTK widget
70 4) Provide the entire mechanism for scrolling widgets. This actual inter-
71 face for this is usually in wxScrolledWindow, but the GTK implementation
74 5) A multitude of helper or extra methods for special purposes, such as
75 Drag'n'Drop, managing validators etc.
77 Normally one might expect, that one wxWindows window would always correspond
78 to one GTK widget. Under GTK, there is no such allround widget that has all
79 the functionality. Moreover, the GTK defines a client area as a different
80 widget from the actual widget you are handling. Last but not least some
81 special classes (e.g. wxFrame) handle different categories of widgets and
82 still have the possibility to draw something in the client area.
83 It was therefore required to write a special purpose GTK widget, that would
84 represent a client area in the sense of wxWindows capable to do the jobs
85 2), 3) and 4). I have written this class and it resides in win_gtk.c of
88 All windows must have a widget, with which they interact with other under-
89 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
90 thw wxWindow class has a member variable called m_widget which holds a
91 pointer to this widget. When the window class represents a GTK native widget,
92 this is (in most cases) the only GTK widget the class manages. E.g. the
93 wxStatitText class handles only a GtkLabel widget a pointer to which you
94 can find in m_widget (defined in wxWindow)
96 When the class has a client area for drawing into and for containing children
97 it has to handle the client area widget (of the type GtkMyFixed, defined in
98 win_gtk.c), but there could be any number of widgets, handled by a class
99 The common rule for all windows is only, that the widget that interacts with
100 the rest of GTK must be referenced in m_widget and all other widgets must be
101 children of this widget on the GTK level. The top-most widget, which also
102 represents the client area, must be in the m_wxwindow field and must be of
105 As I said, the window classes that display a GTK native widget only have
106 one widget, so in the case of e.g. the wxButton class m_widget holds a
107 pointer to a GtkButton widget. But windows with client areas (for drawing
108 and children) have a m_widget field that is a pointer to a GtkScrolled-
109 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
110 one is (in the GTK sense) a child of the GtkScrolledWindow.
112 If the m_wxwindow field is set, then all input to this widget is inter-
113 cepted and sent to the wxWindows class. If not, all input to the widget
114 that gets pointed to by m_widget gets intercepted and sent to the class.
118 //-------------------------------------------------------------------------
119 // conditional compilation
120 //-------------------------------------------------------------------------
122 #if (GTK_MINOR_VERSION == 1)
123 #if (GTK_MICRO_VERSION >= 5)
124 #define NEW_GTK_SCROLL_CODE
128 //-----------------------------------------------------------------------------
130 //-----------------------------------------------------------------------------
134 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
135 GdkEvent
*WXUNUSED(event
),
138 printf( "FOCUS NOW AT: " );
145 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
153 char *s
= new char[tmp
.Length()+1];
155 strcpy( s
, WXSTRINGCAST tmp
);
157 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
158 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
163 //-----------------------------------------------------------------------------
165 //-----------------------------------------------------------------------------
167 extern wxList wxPendingDelete
;
168 extern wxList wxTopLevelWindows
;
169 extern bool g_blockEventsOnDrag
;
170 extern bool g_blockEventsOnScroll
;
171 static bool g_capturing
= FALSE
;
172 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
174 // hack: we need something to pass to gtk_menu_popup, so we store the time of
175 // the last click here
176 static guint32 gs_timeLastClick
= 0;
178 //-----------------------------------------------------------------------------
179 // "expose_event" (of m_wxwindow, not of m_widget)
180 //-----------------------------------------------------------------------------
182 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
184 if (!win
->HasVMT()) return;
186 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
188 gdk_event
->area
.width
,
189 gdk_event
->area
.height
);
191 if (gdk_event
->count
> 0) return;
194 printf( "OnExpose from " );
195 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
196 printf( win->GetClassInfo()->GetClassName() );
200 wxPaintEvent
event( win
->GetId() );
201 event
.SetEventObject( win
);
202 win
->GetEventHandler()->ProcessEvent( event
);
204 win
->m_updateRegion
.Clear();
207 //-----------------------------------------------------------------------------
208 // "draw" (of m_wxwindow, not of m_widget)
209 //-----------------------------------------------------------------------------
211 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
213 if (!win
->HasVMT()) return;
215 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
217 wxPaintEvent
event( win
->GetId() );
218 event
.SetEventObject( win
);
219 win
->GetEventHandler()->ProcessEvent( event
);
221 win
->m_updateRegion
.Clear();
224 //-----------------------------------------------------------------------------
225 // "key_press_event" from any window
226 //-----------------------------------------------------------------------------
228 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
230 if (!win
->HasVMT()) return FALSE
;
231 if (g_blockEventsOnDrag
) return FALSE
;
234 printf( "OnKeyPress from " );
235 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
236 printf( win->GetClassInfo()->GetClassName() );
241 switch (gdk_event
->keyval
)
243 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
244 case GDK_Tab
: key_code
= WXK_TAB
; break;
245 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
246 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
247 case GDK_Return
: key_code
= WXK_RETURN
; break;
248 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
249 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
250 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
251 case GDK_Delete
: key_code
= WXK_DELETE
; break;
252 case GDK_Home
: key_code
= WXK_HOME
; break;
253 case GDK_Left
: key_code
= WXK_LEFT
; break;
254 case GDK_Up
: key_code
= WXK_UP
; break;
255 case GDK_Right
: key_code
= WXK_RIGHT
; break;
256 case GDK_Down
: key_code
= WXK_DOWN
; break;
257 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
258 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
259 case GDK_Next
: key_code
= WXK_NEXT
; break;
260 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
261 case GDK_End
: key_code
= WXK_END
; break;
262 case GDK_Begin
: key_code
= WXK_HOME
; break;
263 case GDK_Select
: key_code
= WXK_SELECT
; break;
264 case GDK_Print
: key_code
= WXK_PRINT
; break;
265 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
266 case GDK_Insert
: key_code
= WXK_INSERT
; break;
267 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
268 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
269 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
270 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
271 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
272 case GDK_KP_Up
: key_code
= WXK_UP
; break;
273 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
274 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
275 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
276 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
277 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
278 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
279 case GDK_KP_End
: key_code
= WXK_END
; break;
280 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
281 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
282 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
283 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
284 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
285 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
286 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
287 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
288 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
289 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
290 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
291 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
292 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
293 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
294 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
295 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
296 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
297 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
298 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
299 case GDK_F1
: key_code
= WXK_F1
; break;
300 case GDK_F2
: key_code
= WXK_F2
; break;
301 case GDK_F3
: key_code
= WXK_F3
; break;
302 case GDK_F4
: key_code
= WXK_F4
; break;
303 case GDK_F5
: key_code
= WXK_F5
; break;
304 case GDK_F6
: key_code
= WXK_F6
; break;
305 case GDK_F7
: key_code
= WXK_F7
; break;
306 case GDK_F8
: key_code
= WXK_F8
; break;
307 case GDK_F9
: key_code
= WXK_F9
; break;
308 case GDK_F10
: key_code
= WXK_F10
; break;
309 case GDK_F11
: key_code
= WXK_F11
; break;
310 case GDK_F12
: key_code
= WXK_F12
; break;
313 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
314 key_code
= gdk_event
->keyval
;
318 if (!key_code
) return FALSE
;
320 wxKeyEvent
event( wxEVT_KEY_DOWN
);
321 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
322 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
323 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
324 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
325 event
.m_keyCode
= key_code
;
328 event
.SetEventObject( win
);
330 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
334 wxWindow
*ancestor
= win
;
337 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
340 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
341 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
344 ancestor
= ancestor
->GetParent();
348 // win is a control: tab can be propagated up
349 if ((!ret
) && (gdk_event
->keyval
== GDK_Tab
))
351 wxNavigationKeyEvent new_event
;
352 new_event
.SetDirection( !(gdk_event
->state
& GDK_SHIFT_MASK
) );
353 new_event
.SetWindowChange( FALSE
);
354 new_event
.SetCurrentFocus( win
);
355 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
359 // win is a panel: up can be propagated to the panel
360 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
361 (gdk_event->keyval == GDK_Up))
363 win->m_parent->SetFocus();
367 // win is a panel: left/right can be propagated to the panel
368 if ((!ret) && (win->m_wxwindow) &&
369 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
370 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
372 wxNavigationKeyEvent new_event;
373 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
374 new_event.SetCurrentFocus( win );
375 ret = win->GetEventHandler()->ProcessEvent( new_event );
381 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
387 //-----------------------------------------------------------------------------
388 // "key_release_event" from any window
389 //-----------------------------------------------------------------------------
391 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
393 if (!win
->HasVMT()) return FALSE
;
394 if (g_blockEventsOnDrag
) return FALSE
;
397 printf( "OnKeyRelease from " );
398 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
399 printf( win->GetClassInfo()->GetClassName() );
404 switch (gdk_event
->keyval
)
406 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
407 case GDK_Tab
: key_code
= WXK_TAB
; break;
408 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
409 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
410 case GDK_Return
: key_code
= WXK_RETURN
; break;
411 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
412 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
413 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
414 case GDK_Delete
: key_code
= WXK_DELETE
; break;
415 case GDK_Home
: key_code
= WXK_HOME
; break;
416 case GDK_Left
: key_code
= WXK_LEFT
; break;
417 case GDK_Up
: key_code
= WXK_UP
; break;
418 case GDK_Right
: key_code
= WXK_RIGHT
; break;
419 case GDK_Down
: key_code
= WXK_DOWN
; break;
420 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
421 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
422 case GDK_Next
: key_code
= WXK_NEXT
; break;
423 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
424 case GDK_End
: key_code
= WXK_END
; break;
425 case GDK_Begin
: key_code
= WXK_HOME
; break;
426 case GDK_Select
: key_code
= WXK_SELECT
; break;
427 case GDK_Print
: key_code
= WXK_PRINT
; break;
428 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
429 case GDK_Insert
: key_code
= WXK_INSERT
; break;
430 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
431 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
432 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
433 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
434 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
435 case GDK_KP_Up
: key_code
= WXK_UP
; break;
436 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
437 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
438 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
439 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
440 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
441 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
442 case GDK_KP_End
: key_code
= WXK_END
; break;
443 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
444 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
445 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
446 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
447 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
448 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
449 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
450 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
451 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
452 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
453 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
454 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
455 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
456 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
457 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
458 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
459 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
460 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
461 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
462 case GDK_F1
: key_code
= WXK_F1
; break;
463 case GDK_F2
: key_code
= WXK_F2
; break;
464 case GDK_F3
: key_code
= WXK_F3
; break;
465 case GDK_F4
: key_code
= WXK_F4
; break;
466 case GDK_F5
: key_code
= WXK_F5
; break;
467 case GDK_F6
: key_code
= WXK_F6
; break;
468 case GDK_F7
: key_code
= WXK_F7
; break;
469 case GDK_F8
: key_code
= WXK_F8
; break;
470 case GDK_F9
: key_code
= WXK_F9
; break;
471 case GDK_F10
: key_code
= WXK_F10
; break;
472 case GDK_F11
: key_code
= WXK_F11
; break;
473 case GDK_F12
: key_code
= WXK_F12
; break;
476 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
477 key_code
= gdk_event
->keyval
;
481 if (!key_code
) return FALSE
;
483 wxKeyEvent
event( wxEVT_KEY_UP
);
484 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
485 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
486 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
487 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
488 event
.m_keyCode
= key_code
;
491 event
.SetEventObject( win
);
493 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
497 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
503 //-----------------------------------------------------------------------------
504 // "button_press_event"
505 //-----------------------------------------------------------------------------
507 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
509 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
511 if (g_blockEventsOnDrag
) return TRUE
;
512 if (g_blockEventsOnScroll
) return TRUE
;
516 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
518 gtk_widget_grab_focus (win
->m_wxwindow
);
521 printf( "GrabFocus from " );
522 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
523 printf( win->GetClassInfo()->GetClassName() );
530 if (!win
->HasVMT()) return TRUE
;
533 printf( "OnButtonPress from " );
534 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
535 printf( win->GetClassInfo()->GetClassName() );
539 wxEventType event_type
= wxEVT_LEFT_DOWN
;
541 if (gdk_event
->button
== 1)
543 switch (gdk_event
->type
)
545 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
546 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
550 else if (gdk_event
->button
== 2)
552 switch (gdk_event
->type
)
554 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
555 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
559 else if (gdk_event
->button
== 3)
561 switch (gdk_event
->type
)
563 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
564 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
569 wxMouseEvent
event( event_type
);
570 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
571 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
572 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
573 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
574 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
575 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
576 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
578 event
.m_x
= (long)gdk_event
->x
;
579 event
.m_y
= (long)gdk_event
->y
;
581 // Some control don't have their own X window and thus cannot get
586 wxNode
*node
= win
->GetChildren().First();
589 wxWindow
*child
= (wxWindow
*)node
->Data();
591 if (child
->m_isStaticBox
)
593 // wxStaticBox is transparent in the box itself
596 int xx1
= child
->m_x
;
597 int yy1
= child
->m_y
;
598 int xx2
= child
->m_x
+ child
->m_width
;
599 int yy2
= child
->m_x
+ child
->m_height
;
602 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
604 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
606 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
608 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
611 event
.m_x
-= child
->m_x
;
612 event
.m_y
-= child
->m_y
;
619 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
620 (child
->m_x
<= event
.m_x
) &&
621 (child
->m_y
<= event
.m_y
) &&
622 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
623 (child
->m_y
+child
->m_height
>= event
.m_y
))
626 event
.m_x
-= child
->m_x
;
627 event
.m_y
-= child
->m_y
;
635 event
.SetEventObject( win
);
637 gs_timeLastClick
= gdk_event
->time
;
639 if (win
->GetEventHandler()->ProcessEvent( event
))
640 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
645 //-----------------------------------------------------------------------------
646 // "button_release_event"
647 //-----------------------------------------------------------------------------
649 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
651 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
653 if (g_blockEventsOnDrag
) return TRUE
;
654 if (g_blockEventsOnScroll
) return TRUE
;
656 if (!win
->HasVMT()) return TRUE
;
659 printf( "OnButtonRelease from " );
660 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
661 printf( win->GetClassInfo()->GetClassName() );
665 wxEventType event_type
= wxEVT_NULL
;
667 switch (gdk_event
->button
)
669 case 1: event_type
= wxEVT_LEFT_UP
; break;
670 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
671 case 3: event_type
= wxEVT_RIGHT_UP
; break;
674 wxMouseEvent
event( event_type
);
675 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
676 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
677 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
678 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
679 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
680 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
681 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
682 event
.m_x
= (long)gdk_event
->x
;
683 event
.m_y
= (long)gdk_event
->y
;
685 // Some control don't have their own X window and thus cannot get
690 wxNode
*node
= win
->GetChildren().First();
693 wxWindow
*child
= (wxWindow
*)node
->Data();
695 if (child
->m_isStaticBox
)
697 // wxStaticBox is transparent in the box itself
700 int xx1
= child
->m_x
;
701 int yy1
= child
->m_y
;
702 int xx2
= child
->m_x
+ child
->m_width
;
703 int yy2
= child
->m_x
+ child
->m_height
;
706 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
708 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
710 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
712 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
715 event
.m_x
-= child
->m_x
;
716 event
.m_y
-= child
->m_y
;
723 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
724 (child
->m_x
<= event
.m_x
) &&
725 (child
->m_y
<= event
.m_y
) &&
726 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
727 (child
->m_y
+child
->m_height
>= event
.m_y
))
730 event
.m_x
-= child
->m_x
;
731 event
.m_y
-= child
->m_y
;
739 event
.SetEventObject( win
);
741 if (win
->GetEventHandler()->ProcessEvent( event
))
742 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
747 //-----------------------------------------------------------------------------
748 // "motion_notify_event"
749 //-----------------------------------------------------------------------------
751 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
753 if (gdk_event
->is_hint
)
757 GdkModifierType state
;
758 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
761 gdk_event
->state
= state
;
764 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
766 if (g_blockEventsOnDrag
) return TRUE
;
767 if (g_blockEventsOnScroll
) return TRUE
;
769 if (!win
->HasVMT()) return TRUE
;
772 printf( "OnMotion from " );
773 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
774 printf( win->GetClassInfo()->GetClassName() );
778 wxMouseEvent
event( wxEVT_MOTION
);
779 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
780 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
781 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
782 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
783 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
784 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
785 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
787 event
.m_x
= (long)gdk_event
->x
;
788 event
.m_y
= (long)gdk_event
->y
;
790 // Some control don't have their own X window and thus cannot get
795 wxNode
*node
= win
->GetChildren().First();
798 wxWindow
*child
= (wxWindow
*)node
->Data();
800 if (child
->m_isStaticBox
)
802 // wxStaticBox is transparent in the box itself
805 int xx1
= child
->m_x
;
806 int yy1
= child
->m_y
;
807 int xx2
= child
->m_x
+ child
->m_width
;
808 int yy2
= child
->m_x
+ child
->m_height
;
811 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
813 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
815 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
817 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
820 event
.m_x
-= child
->m_x
;
821 event
.m_y
-= child
->m_y
;
828 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
829 (child
->m_x
<= event
.m_x
) &&
830 (child
->m_y
<= event
.m_y
) &&
831 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
832 (child
->m_y
+child
->m_height
>= event
.m_y
))
835 event
.m_x
-= child
->m_x
;
836 event
.m_y
-= child
->m_y
;
844 event
.SetEventObject( win
);
846 if (win
->GetEventHandler()->ProcessEvent( event
))
847 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
852 //-----------------------------------------------------------------------------
854 //-----------------------------------------------------------------------------
856 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
858 if (g_blockEventsOnDrag
) return TRUE
;
864 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
866 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
868 printf( "SetFocus flag from " );
869 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
870 printf( win->GetClassInfo()->GetClassName() );
876 if (!win
->HasVMT()) return TRUE
;
879 printf( "OnSetFocus from " );
880 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
881 printf( win->GetClassInfo()->GetClassName() );
883 printf( WXSTRINGCAST win->GetLabel() );
887 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
888 event
.SetEventObject( win
);
890 if (win
->GetEventHandler()->ProcessEvent( event
))
891 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
896 //-----------------------------------------------------------------------------
898 //-----------------------------------------------------------------------------
900 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
902 if (g_blockEventsOnDrag
) return TRUE
;
905 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
906 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
909 if (!win
->HasVMT()) return TRUE
;
912 printf( "OnKillFocus from " );
913 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
914 printf( win->GetClassInfo()->GetClassName() );
918 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
919 event
.SetEventObject( win
);
921 if (win
->GetEventHandler()->ProcessEvent( event
))
922 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
927 //-----------------------------------------------------------------------------
928 // "enter_notify_event"
929 //-----------------------------------------------------------------------------
931 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
933 if (g_blockEventsOnDrag
) return TRUE
;
935 if ((widget
->window
) && (win
->m_cursor
))
936 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
938 if (widget
->window
!= gdk_event
->window
) return TRUE
;
940 if (!win
->HasVMT()) return TRUE
;
943 printf( "OnEnter from " );
944 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
945 printf( win->GetClassInfo()->GetClassName() );
949 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
950 event
.SetEventObject( win
);
954 GdkModifierType state
= (GdkModifierType
)0;
956 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
958 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
959 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
960 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
961 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
962 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
963 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
964 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
969 if (win
->GetEventHandler()->ProcessEvent( event
))
970 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
975 //-----------------------------------------------------------------------------
976 // "leave_notify_event"
977 //-----------------------------------------------------------------------------
979 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
981 if (g_blockEventsOnDrag
) return TRUE
;
983 if ((widget
->window
) && (win
->m_cursor
))
984 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
986 if (widget
->window
!= gdk_event
->window
) return TRUE
;
988 if (!win
->HasVMT()) return TRUE
;
991 printf( "OnLeave from " );
992 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
993 printf( win->GetClassInfo()->GetClassName() );
997 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
998 event
.SetEventObject( win
);
1002 GdkModifierType state
= (GdkModifierType
)0;
1004 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1006 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1007 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1008 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1009 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1010 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1011 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1012 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1014 event
.m_x
= (long)x
;
1015 event
.m_y
= (long)y
;
1017 if (win
->GetEventHandler()->ProcessEvent( event
))
1018 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1023 //-----------------------------------------------------------------------------
1024 // "value_changed" from m_vAdjust
1025 //-----------------------------------------------------------------------------
1027 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1029 if (g_blockEventsOnDrag
) return;
1032 printf( "OnVScroll from " );
1033 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1034 printf( win->GetClassInfo()->GetClassName() );
1038 if (!win
->HasVMT()) return;
1040 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1041 if (fabs(diff
) < 0.2) return;
1043 wxEventType command
= wxEVT_NULL
;
1045 float line_step
= win
->m_vAdjust
->step_increment
;
1046 float page_step
= win
->m_vAdjust
->page_increment
;
1048 if (win
->m_isScrolling
)
1050 command
= wxEVT_SCROLL_THUMBTRACK
;
1054 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1055 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1056 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1057 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1058 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1059 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1060 else command
= wxEVT_SCROLL_THUMBTRACK
;
1063 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1065 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1066 event
.SetEventObject( win
);
1067 win
->GetEventHandler()->ProcessEvent( event
);
1070 //-----------------------------------------------------------------------------
1071 // "value_changed" from m_hAdjust
1072 //-----------------------------------------------------------------------------
1074 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1076 if (g_blockEventsOnDrag
) return;
1079 printf( "OnHScroll from " );
1080 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1081 printf( win->GetClassInfo()->GetClassName() );
1085 if (!win
->HasVMT()) return;
1087 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1088 if (fabs(diff
) < 0.2) return;
1090 wxEventType command
= wxEVT_NULL
;
1092 float line_step
= win
->m_hAdjust
->step_increment
;
1093 float page_step
= win
->m_hAdjust
->page_increment
;
1095 if (win
->m_isScrolling
)
1097 command
= wxEVT_SCROLL_THUMBTRACK
;
1101 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1102 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1103 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1104 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1105 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1106 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1107 else command
= wxEVT_SCROLL_THUMBTRACK
;
1110 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1112 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1113 event
.SetEventObject( win
);
1114 win
->GetEventHandler()->ProcessEvent( event
);
1117 //-----------------------------------------------------------------------------
1118 // "changed" from m_vAdjust
1119 //-----------------------------------------------------------------------------
1121 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1123 if (g_blockEventsOnDrag
) return;
1126 printf( "OnVScroll change from " );
1127 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1128 printf( win->GetClassInfo()->GetClassName() );
1132 if (!win
->HasVMT()) return;
1134 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1135 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1137 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1138 event
.SetEventObject( win
);
1139 win
->GetEventHandler()->ProcessEvent( event
);
1142 //-----------------------------------------------------------------------------
1143 // "changed" from m_hAdjust
1144 //-----------------------------------------------------------------------------
1146 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1148 if (g_blockEventsOnDrag
) return;
1151 printf( "OnHScroll change from " );
1152 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1153 printf( win->GetClassInfo()->GetClassName() );
1157 if (!win
->HasVMT()) return;
1159 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1160 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1162 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1163 event
.SetEventObject( win
);
1164 win
->GetEventHandler()->ProcessEvent( event
);
1167 //-----------------------------------------------------------------------------
1168 // "button_press_event" from scrollbar
1169 //-----------------------------------------------------------------------------
1171 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1172 GdkEventButton
*WXUNUSED(gdk_event
),
1175 // don't test here as we can release the mouse while being over
1176 // a different window then the slider
1178 // if (gdk_event->window != widget->slider) return FALSE;
1180 win
->m_isScrolling
= TRUE
;
1181 g_blockEventsOnScroll
= TRUE
;
1186 //-----------------------------------------------------------------------------
1187 // "button_release_event" from scrollbar
1188 //-----------------------------------------------------------------------------
1190 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1191 GdkEventButton
*WXUNUSED(gdk_event
),
1195 // don't test here as we can release the mouse while being over
1196 // a different window then the slider
1198 // if (gdk_event->window != widget->slider) return FALSE;
1200 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1202 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1203 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1205 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1207 win
->m_isScrolling
= FALSE
;
1208 g_blockEventsOnScroll
= FALSE
;
1213 //-----------------------------------------------------------------------------
1214 // InsertChild for wxWindow.
1215 //-----------------------------------------------------------------------------
1217 // Callback for wxWindow. This very strange beast has to be used because
1218 // C++ has no virtual methods in a constructor. We have to emulate a
1219 // virtual function here as wxNotebook requires a different way to insert
1220 // a child in it. I had opted for creating a wxNotebookPage window class
1221 // which would have made this superfluous (such in the MDI window system),
1222 // but no-one was listening to me...
1224 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1226 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1227 GTK_WIDGET(child
->m_widget
),
1231 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1235 if (wxIS_KIND_OF(parent
,wxFrame
))
1237 parent
->m_sizeSet
= FALSE
;
1241 //-----------------------------------------------------------------------------
1243 //-----------------------------------------------------------------------------
1245 wxWindow
* wxGetActiveWindow()
1247 return g_focusWindow
;
1250 //-----------------------------------------------------------------------------
1252 //-----------------------------------------------------------------------------
1254 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1256 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1257 EVT_SIZE(wxWindow::OnSize
)
1258 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1259 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1260 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1263 wxWindow::wxWindow()
1265 m_widget
= (GtkWidget
*) NULL
;
1266 m_wxwindow
= (GtkWidget
*) NULL
;
1267 m_parent
= (wxWindow
*) NULL
;
1268 m_children
.DeleteContents( FALSE
);
1281 m_eventHandler
= this;
1282 m_windowValidator
= (wxValidator
*) NULL
;
1286 m_cursor
= (wxCursor
*) NULL
;
1287 m_font
= *wxSWISS_FONT
;
1289 m_windowName
= "noname";
1291 m_constraints
= (wxLayoutConstraints
*) NULL
;
1292 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1293 m_windowSizer
= (wxSizer
*) NULL
;
1294 m_sizerParent
= (wxWindow
*) NULL
;
1295 m_autoLayout
= FALSE
;
1299 m_needParent
= TRUE
;
1301 m_hasScrolling
= FALSE
;
1302 m_isScrolling
= FALSE
;
1303 m_hAdjust
= (GtkAdjustment
*) NULL
;
1304 m_vAdjust
= (GtkAdjustment
*) NULL
;
1305 m_oldHorizontalPos
= 0.0;
1306 m_oldVerticalPos
= 0.0;
1311 #if wxUSE_DRAG_AND_DROP
1312 m_dropTarget
= (wxDropTarget
*) NULL
;
1315 m_scrollGC
= (GdkGC
*) NULL
;
1316 m_widgetStyle
= (GtkStyle
*) NULL
;
1318 m_insertCallback
= wxInsertChildInWindow
;
1320 m_clientObject
= (wxClientData
*) NULL
;
1321 m_clientData
= NULL
;
1323 m_isStaticBox
= FALSE
;
1324 m_acceptsFocus
= FALSE
;
1327 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1328 const wxPoint
&pos
, const wxSize
&size
,
1329 long style
, const wxString
&name
)
1331 m_insertCallback
= wxInsertChildInWindow
;
1332 Create( parent
, id
, pos
, size
, style
, name
);
1335 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1336 const wxPoint
&pos
, const wxSize
&size
,
1337 long style
, const wxString
&name
)
1341 m_needParent
= TRUE
;
1343 PreCreation( parent
, id
, pos
, size
, style
, name
);
1345 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1346 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1349 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1352 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1355 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1356 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1359 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1360 scroll_class
->scrollbar_spacing
= 0;
1362 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1364 m_oldHorizontalPos
= 0.0;
1365 m_oldVerticalPos
= 0.0;
1367 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1368 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1370 m_wxwindow
= gtk_myfixed_new();
1373 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1376 #ifdef NEW_GTK_SCROLL_CODE
1377 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1378 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1380 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1381 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1385 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1388 if (m_windowStyle
& wxRAISED_BORDER
)
1390 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1392 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1394 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1398 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1401 if ((m_windowStyle
& wxTAB_TRAVERSAL
) != 0)
1403 GTK_WIDGET_UNSET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1404 m_acceptsFocus
= FALSE
;
1408 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1409 m_acceptsFocus
= TRUE
;
1412 // shut the viewport up
1413 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1414 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1416 // I _really_ don't want scrollbars in the beginning
1417 m_vAdjust
->lower
= 0.0;
1418 m_vAdjust
->upper
= 1.0;
1419 m_vAdjust
->value
= 0.0;
1420 m_vAdjust
->step_increment
= 1.0;
1421 m_vAdjust
->page_increment
= 1.0;
1422 m_vAdjust
->page_size
= 5.0;
1423 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1424 m_hAdjust
->lower
= 0.0;
1425 m_hAdjust
->upper
= 1.0;
1426 m_hAdjust
->value
= 0.0;
1427 m_hAdjust
->step_increment
= 1.0;
1428 m_hAdjust
->page_increment
= 1.0;
1429 m_hAdjust
->page_size
= 5.0;
1430 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1432 // these handlers block mouse events to any window during scrolling
1433 // such as motion events and prevent GTK and wxWindows from fighting
1434 // over where the slider should be
1436 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1437 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1439 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1440 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1442 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1443 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1445 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1446 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1448 // these handers het notified when screen updates are required either when
1449 // scrolling or when the window size (and therefore scrollbar configuration)
1452 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1453 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1454 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1455 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1457 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1458 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1459 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1460 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1462 gtk_widget_show( m_wxwindow
);
1464 if (m_parent
) m_parent
->AddChild( this );
1466 (m_parent
->m_insertCallback
)( m_parent
, this );
1475 wxWindow::~wxWindow()
1479 #if wxUSE_DRAG_AND_DROP
1480 if (m_dropTarget
) delete m_dropTarget
;
1483 if (m_parent
) m_parent
->RemoveChild( this );
1484 if (m_widget
) Show( FALSE
);
1488 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1490 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1492 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1494 if (m_widget
) gtk_widget_destroy( m_widget
);
1496 if (m_cursor
) delete m_cursor
;
1498 DeleteRelatedConstraints();
1501 // This removes any dangling pointers to this window
1502 // in other windows' constraintsInvolvedIn lists.
1503 UnsetConstraints(m_constraints
);
1504 delete m_constraints
;
1505 m_constraints
= (wxLayoutConstraints
*) NULL
;
1509 delete m_windowSizer
;
1510 m_windowSizer
= (wxSizer
*) NULL
;
1512 // If this is a child of a sizer, remove self from parent
1513 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1515 // Just in case the window has been Closed, but
1516 // we're then deleting immediately: don't leave
1517 // dangling pointers.
1518 wxPendingDelete
.DeleteObject(this);
1520 // Just in case we've loaded a top-level window via
1521 // wxWindow::LoadNativeDialog but we weren't a dialog
1523 wxTopLevelWindows
.DeleteObject(this);
1525 if (m_windowValidator
) delete m_windowValidator
;
1527 if (m_clientObject
) delete m_clientObject
;
1530 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1531 const wxPoint
&pos
, const wxSize
&size
,
1532 long style
, const wxString
&name
)
1534 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1536 m_widget
= (GtkWidget
*) NULL
;
1537 m_wxwindow
= (GtkWidget
*) NULL
;
1540 m_children
.DeleteContents( FALSE
);
1543 if (m_width
== -1) m_width
= 20;
1545 if (m_height
== -1) m_height
= 20;
1550 if (!m_needParent
) // some reasonable defaults
1554 m_x
= (gdk_screen_width () - m_width
) / 2;
1555 if (m_x
< 10) m_x
= 10;
1559 m_y
= (gdk_screen_height () - m_height
) / 2;
1560 if (m_y
< 10) m_y
= 10;
1571 m_eventHandler
= this;
1573 m_windowId
= id
== -1 ? wxNewId() : id
;
1577 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1578 m_font
= *wxSWISS_FONT
;
1579 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1580 m_foregroundColour
= *wxBLACK
;
1581 m_windowStyle
= style
;
1582 m_windowName
= name
;
1584 m_constraints
= (wxLayoutConstraints
*) NULL
;
1585 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1586 m_windowSizer
= (wxSizer
*) NULL
;
1587 m_sizerParent
= (wxWindow
*) NULL
;
1588 m_autoLayout
= FALSE
;
1590 m_hasScrolling
= FALSE
;
1591 m_isScrolling
= FALSE
;
1592 m_hAdjust
= (GtkAdjustment
*) NULL
;
1593 m_vAdjust
= (GtkAdjustment
*) NULL
;
1594 m_oldHorizontalPos
= 0.0;
1595 m_oldVerticalPos
= 0.0;
1600 #if wxUSE_DRAG_AND_DROP
1601 m_dropTarget
= (wxDropTarget
*) NULL
;
1604 m_windowValidator
= (wxValidator
*) NULL
;
1605 m_scrollGC
= (GdkGC
*) NULL
;
1606 m_widgetStyle
= (GtkStyle
*) NULL
;
1608 m_clientObject
= (wxClientData
*)NULL
;
1609 m_clientData
= NULL
;
1611 m_isStaticBox
= FALSE
;
1614 void wxWindow::PostCreation()
1618 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1619 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1621 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1622 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1625 ConnectWidget( GetConnectWidget() );
1627 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1629 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1631 SetCursor( *wxSTANDARD_CURSOR
);
1636 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1638 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1639 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1641 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1642 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1644 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1645 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1647 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1648 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1650 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1651 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1653 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1654 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1656 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1657 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1659 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1660 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1662 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1663 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1666 bool wxWindow::HasVMT()
1671 bool wxWindow::Close( bool force
)
1673 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1675 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1676 event
.SetEventObject(this);
1677 event
.SetForce(force
);
1679 return GetEventHandler()->ProcessEvent(event
);
1682 bool wxWindow::Destroy()
1684 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1691 bool wxWindow::DestroyChildren()
1694 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1697 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1700 if (m_children
.Member(child
)) delete node
;
1706 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1708 // are we to set fonts here ?
1711 wxPoint
wxWindow::GetClientAreaOrigin() const
1713 return wxPoint(0,0);
1716 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1718 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1720 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1726 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1728 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1729 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1731 if (m_resizing
) return; // I don't like recursions
1734 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1736 // don't set the size for children of wxNotebook, just take the values.
1744 int old_width
= m_width
;
1745 int old_height
= m_height
;
1747 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1749 if (x
!= -1) m_x
= x
;
1750 if (y
!= -1) m_y
= y
;
1751 if (width
!= -1) m_width
= width
;
1752 if (height
!= -1) m_height
= height
;
1762 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1764 if (width
== -1) m_width
= 80;
1767 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1769 if (height
== -1) m_height
= 26;
1772 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1773 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1774 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1775 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1777 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1778 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1780 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1781 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1786 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1787 event
.SetEventObject( this );
1788 GetEventHandler()->ProcessEvent( event
);
1793 void wxWindow::OnInternalIdle()
1798 void wxWindow::SetSize( int width
, int height
)
1800 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1803 void wxWindow::Move( int x
, int y
)
1805 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1808 void wxWindow::GetSize( int *width
, int *height
) const
1810 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1812 if (width
) (*width
) = m_width
;
1813 if (height
) (*height
) = m_height
;
1816 void wxWindow::SetClientSize( int width
, int height
)
1818 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1822 SetSize( width
, height
);
1829 if (!m_hasScrolling
)
1831 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1833 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1834 (m_windowStyle
& wxSUNKEN_BORDER
))
1836 dw
+= 2 * window_class
->xthickness
;
1837 dh
+= 2 * window_class
->ythickness
;
1842 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1843 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1845 #ifdef NEW_GTK_SCROLL_CODE
1846 GtkWidget
*viewport
= scroll_window
->child
;
1848 GtkWidget
*viewport
= scroll_window
->viewport
;
1851 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1853 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1854 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1856 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1857 (m_windowStyle
& wxSUNKEN_BORDER
))
1859 dw
+= 2 * viewport_class
->xthickness
;
1860 dh
+= 2 * viewport_class
->ythickness
;
1863 if (scroll_window
->vscrollbar_visible
)
1865 dw
+= vscrollbar
->allocation
.width
;
1866 dw
+= scroll_class
->scrollbar_spacing
;
1869 if (scroll_window
->hscrollbar_visible
)
1871 dh
+= hscrollbar
->allocation
.height
;
1872 dw
+= scroll_class
->scrollbar_spacing
;
1876 SetSize( width
+dw
, height
+dh
);
1880 void wxWindow::GetClientSize( int *width
, int *height
) const
1882 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1886 if (width
) (*width
) = m_width
;
1887 if (height
) (*height
) = m_height
;
1894 if (!m_hasScrolling
)
1896 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1898 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1899 (m_windowStyle
& wxSUNKEN_BORDER
))
1901 dw
+= 2 * window_class
->xthickness
;
1902 dh
+= 2 * window_class
->ythickness
;
1907 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1908 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1910 #ifdef NEW_GTK_SCROLL_CODE
1911 GtkWidget
*viewport
= scroll_window
->child
;
1913 GtkWidget
*viewport
= scroll_window
->viewport
;
1916 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1918 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1919 (m_windowStyle
& wxSUNKEN_BORDER
))
1921 dw
+= 2 * viewport_class
->xthickness
;
1922 dh
+= 2 * viewport_class
->ythickness
;
1925 if (scroll_window
->vscrollbar_visible
)
1927 // dw += vscrollbar->allocation.width;
1928 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1929 dw
+= scroll_class
->scrollbar_spacing
;
1932 if (scroll_window
->hscrollbar_visible
)
1934 // dh += hscrollbar->allocation.height;
1936 dh
+= scroll_class
->scrollbar_spacing
;
1940 if (width
) (*width
) = m_width
- dw
;
1941 if (height
) (*height
) = m_height
- dh
;
1945 void wxWindow::GetPosition( int *x
, int *y
) const
1947 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1953 void wxWindow::ClientToScreen( int *x
, int *y
)
1955 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1957 GdkWindow
*source
= (GdkWindow
*) NULL
;
1959 source
= m_wxwindow
->window
;
1961 source
= m_widget
->window
;
1965 gdk_window_get_origin( source
, &org_x
, &org_y
);
1969 if (GTK_WIDGET_NO_WINDOW (m_widget
))
1971 org_x
+= m_widget
->allocation
.x
;
1972 org_y
+= m_widget
->allocation
.y
;
1976 wxPoint
pt(GetClientAreaOrigin());
1984 void wxWindow::ScreenToClient( int *x
, int *y
)
1986 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1988 GdkWindow
*source
= (GdkWindow
*) NULL
;
1990 source
= m_wxwindow
->window
;
1992 source
= m_widget
->window
;
1996 gdk_window_get_origin( source
, &org_x
, &org_y
);
2000 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2002 org_x
+= m_widget
->allocation
.x
;
2003 org_y
+= m_widget
->allocation
.y
;
2007 wxPoint
pt(GetClientAreaOrigin());
2015 void wxWindow::Centre( int direction
)
2017 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2026 m_parent
->GetSize( &p_w
, &p_h
);
2027 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2028 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2032 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2033 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2039 void wxWindow::Fit()
2041 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2045 wxNode
*node
= m_children
.First();
2048 wxWindow
*win
= (wxWindow
*)node
->Data();
2050 win
->GetPosition(&wx
, &wy
);
2051 win
->GetSize(&ww
, &wh
);
2052 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2053 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2055 node
= node
->Next();
2058 SetClientSize(maxX
+ 7, maxY
+ 14);
2061 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2063 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2071 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2073 // if (GetAutoLayout()) Layout();
2076 bool wxWindow::Show( bool show
)
2078 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2081 gtk_widget_show( m_widget
);
2083 gtk_widget_hide( m_widget
);
2090 void wxWindow::Enable( bool enable
)
2092 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2094 m_isEnabled
= enable
;
2096 gtk_widget_set_sensitive( m_widget
, enable
);
2097 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2100 int wxWindow::GetCharHeight() const
2102 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2104 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2106 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2108 return font
->ascent
+ font
->descent
;
2111 int wxWindow::GetCharWidth() const
2113 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2115 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2117 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2119 return gdk_string_width( font
, "H" );
2122 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2123 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2125 wxFont fontToUse
= m_font
;
2126 if (theFont
) fontToUse
= *theFont
;
2128 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2130 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2131 if (x
) (*x
) = gdk_string_width( font
, string
);
2132 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2133 if (descent
) (*descent
) = font
->descent
;
2134 if (externalLeading
) (*externalLeading
) = 0; // ??
2137 void wxWindow::MakeModal( bool modal
)
2141 // Disable all other windows
2142 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2144 wxNode
*node
= wxTopLevelWindows
.First();
2147 wxWindow
*win
= (wxWindow
*)node
->Data();
2148 if (win
!= this) win
->Enable(!modal
);
2150 node
= node
->Next();
2155 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2157 event
.SetEventType( wxEVT_CHAR
);
2159 if (!GetEventHandler()->ProcessEvent( event
))
2165 void wxWindow::SetFocus()
2167 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2169 GtkWidget
*connect_widget
= GetConnectWidget();
2172 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2174 gtk_widget_grab_focus (connect_widget
);
2176 else if (GTK_IS_CONTAINER(connect_widget
))
2178 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2186 wxWindow
*wxWindow::FindFocus()
2188 return g_focusWindow
;
2191 bool wxWindow::AcceptsFocus() const
2193 return IsEnabled() && IsShown() && m_acceptsFocus
;
2196 bool wxWindow::OnClose()
2201 void wxWindow::AddChild( wxWindow
*child
)
2203 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2204 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2206 m_children
.Append( child
);
2209 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2211 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2213 wxWindow
*oldParent
= GetParent();
2215 if (oldParent
) oldParent
->RemoveChild( this );
2217 gtk_widget_unparent( m_widget
);
2221 newParent
->AddChild( this );
2222 (newParent
->m_insertCallback
)( newParent
, this );
2228 void wxWindow::RemoveChild( wxWindow
*child
)
2230 m_children
.DeleteObject( child
);
2231 child
->m_parent
= (wxWindow
*) NULL
;
2234 void wxWindow::SetReturnCode( int retCode
)
2236 m_retCode
= retCode
;
2239 int wxWindow::GetReturnCode()
2244 void wxWindow::Raise()
2246 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2248 if (m_widget
) gdk_window_raise( m_widget
->window
);
2251 void wxWindow::Lower()
2253 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2255 if (m_widget
) gdk_window_lower( m_widget
->window
);
2258 wxEvtHandler
*wxWindow::GetEventHandler() const
2260 return m_eventHandler
;
2263 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2265 m_eventHandler
= handler
;
2268 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2270 handler
->SetNextHandler(GetEventHandler());
2271 SetEventHandler(handler
);
2274 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2276 if (GetEventHandler())
2278 wxEvtHandler
*handlerA
= GetEventHandler();
2279 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2280 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2281 SetEventHandler(handlerB
);
2285 return (wxEvtHandler
*) NULL
;
2291 return (wxEvtHandler
*) NULL
;
2294 wxValidator
*wxWindow::GetValidator()
2296 return m_windowValidator
;
2299 void wxWindow::SetValidator( const wxValidator
& validator
)
2301 if (m_windowValidator
) delete m_windowValidator
;
2302 m_windowValidator
= validator
.Clone();
2303 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2306 void wxWindow::SetClientObject( wxClientData
*data
)
2308 if (m_clientObject
) delete m_clientObject
;
2309 m_clientObject
= data
;
2312 wxClientData
*wxWindow::GetClientObject()
2314 return m_clientObject
;
2317 void wxWindow::SetClientData( void *data
)
2319 m_clientData
= data
;
2322 void *wxWindow::GetClientData()
2324 return m_clientData
;
2327 bool wxWindow::IsBeingDeleted()
2332 void wxWindow::SetId( wxWindowID id
)
2337 wxWindowID
wxWindow::GetId() const
2342 void wxWindow::SetCursor( const wxCursor
&cursor
)
2344 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2348 if (cursor
== *m_cursor
) return;
2353 *m_cursor
= *wxSTANDARD_CURSOR
;
2356 if ((m_widget
) && (m_widget
->window
))
2357 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2359 if ((m_wxwindow
) && (m_wxwindow
->window
))
2360 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2363 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2368 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2370 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2372 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2376 gdk_window_clear_area( m_wxwindow
->window
,
2390 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2392 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2396 GdkRectangle gdk_rect
;
2397 gdk_rect
.x
= rect
->x
;
2398 gdk_rect
.y
= rect
->y
;
2399 gdk_rect
.width
= rect
->width
;
2400 gdk_rect
.height
= rect
->height
;
2403 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2405 gtk_widget_draw( m_widget
, &gdk_rect
);
2409 wxRegion
wxWindow::GetUpdateRegion() const
2411 return m_updateRegion
;
2414 bool wxWindow::IsExposed( int x
, int y
) const
2416 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2419 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2421 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2424 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2426 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2429 bool wxWindow::IsExposed( const wxRect
& rect
) const
2431 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2434 void wxWindow::Clear()
2436 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2438 if (m_wxwindow
&& m_wxwindow
->window
) gdk_window_clear( m_wxwindow
->window
);
2441 wxColour
wxWindow::GetBackgroundColour() const
2443 return m_backgroundColour
;
2446 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2448 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2450 if (m_backgroundColour
== colour
) return;
2452 m_backgroundColour
= colour
;
2453 if (!m_backgroundColour
.Ok()) return;
2457 GdkWindow
*window
= m_wxwindow
->window
;
2458 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( window
) );
2459 gdk_window_set_background( window
, m_backgroundColour
.GetColor() );
2460 gdk_window_clear( window
);
2463 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2464 if (sysbg
.Red() == colour
.Red() &&
2465 sysbg
.Green() == colour
.Green() &&
2466 sysbg
.Blue() == colour
.Blue())
2468 m_backgroundColour
= wxNullColour
;
2470 m_backgroundColour
= sysbg
;
2478 wxColour
wxWindow::GetForegroundColour() const
2480 return m_foregroundColour
;
2483 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2485 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2487 if (m_foregroundColour
== colour
) return;
2489 m_foregroundColour
= colour
;
2490 if (!m_foregroundColour
.Ok()) return;
2492 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2493 if (sysbg
.Red() == colour
.Red() &&
2494 sysbg
.Green() == colour
.Green() &&
2495 sysbg
.Blue() == colour
.Blue())
2497 m_backgroundColour
= wxNullColour
;
2499 m_backgroundColour
= sysbg
;
2507 GtkStyle
*wxWindow::GetWidgetStyle()
2509 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2513 gtk_widget_get_style( m_widget
) );
2515 return m_widgetStyle
;
2518 void wxWindow::SetWidgetStyle()
2520 GtkStyle
*style
= GetWidgetStyle();
2522 gdk_font_unref( style
->font
);
2523 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2525 if (m_foregroundColour
.Ok())
2527 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2528 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2529 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2530 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2533 if (m_backgroundColour
.Ok())
2535 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2536 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2537 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2538 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2539 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2540 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2541 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2542 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2543 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2547 void wxWindow::ApplyWidgetStyle()
2551 bool wxWindow::Validate()
2553 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2555 wxNode
*node
= m_children
.First();
2558 wxWindow
*child
= (wxWindow
*)node
->Data();
2559 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2563 node
= node
->Next();
2568 bool wxWindow::TransferDataToWindow()
2570 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2572 wxNode
*node
= m_children
.First();
2575 wxWindow
*child
= (wxWindow
*)node
->Data();
2576 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2577 !child
->GetValidator()->TransferToWindow() )
2579 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2582 node
= node
->Next();
2587 bool wxWindow::TransferDataFromWindow()
2589 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2591 wxNode
*node
= m_children
.First();
2594 wxWindow
*child
= (wxWindow
*)node
->Data();
2595 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2599 node
= node
->Next();
2604 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2606 m_acceleratorTable
= accel
;
2609 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2611 TransferDataToWindow();
2614 void wxWindow::InitDialog()
2616 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2618 wxInitDialogEvent
event(GetId());
2619 event
.SetEventObject( this );
2620 GetEventHandler()->ProcessEvent(event
);
2623 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2625 menu
->SetInvokingWindow( win
);
2626 wxNode
*node
= menu
->m_items
.First();
2629 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2630 if (menuitem
->IsSubMenu())
2632 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2634 node
= node
->Next();
2638 bool wxWindow::PopupMenu( wxMenu
*menu
, int WXUNUSED(x
), int WXUNUSED(y
) )
2640 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2642 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2644 SetInvokingWindow( menu
, this );
2646 GTK_MENU(menu
->m_menu
),
2647 (GtkWidget
*)NULL
, // parent menu shell
2648 (GtkWidget
*)NULL
, // parent menu item
2649 (GtkMenuPositionFunc
)NULL
,
2650 NULL
, // client data
2651 0, // button used to activate it
2652 0//gs_timeLastClick // the time of activation
2657 #if wxUSE_DRAG_AND_DROP
2659 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2661 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2663 GtkWidget
*dnd_widget
= GetConnectWidget();
2665 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2667 if (m_dropTarget
) delete m_dropTarget
;
2668 m_dropTarget
= dropTarget
;
2670 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2673 wxDropTarget
*wxWindow::GetDropTarget() const
2675 return m_dropTarget
;
2680 GtkWidget
* wxWindow::GetConnectWidget()
2682 GtkWidget
*connect_widget
= m_widget
;
2683 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2685 return connect_widget
;
2688 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2690 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2691 return (window
== m_widget
->window
);
2694 void wxWindow::SetFont( const wxFont
&font
)
2696 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2698 if (((wxFont
*)&font
)->Ok())
2701 m_font
= *wxSWISS_FONT
;
2703 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2704 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2705 sysbg
.Green() == m_backgroundColour
.Green() &&
2706 sysbg
.Blue() == m_backgroundColour
.Blue())
2708 m_backgroundColour
= wxNullColour
;
2710 m_backgroundColour
= sysbg
;
2718 void wxWindow::SetWindowStyleFlag( long flag
)
2720 m_windowStyle
= flag
;
2723 long wxWindow::GetWindowStyleFlag() const
2725 return m_windowStyle
;
2728 void wxWindow::CaptureMouse()
2730 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2732 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2734 GtkWidget
*connect_widget
= GetConnectWidget();
2735 gtk_grab_add( connect_widget
);
2736 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2738 (GDK_BUTTON_PRESS_MASK
|
2739 GDK_BUTTON_RELEASE_MASK
|
2740 GDK_POINTER_MOTION_MASK
),
2747 void wxWindow::ReleaseMouse()
2749 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2751 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2753 GtkWidget
*connect_widget
= GetConnectWidget();
2754 gtk_grab_remove( connect_widget
);
2755 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2756 g_capturing
= FALSE
;
2759 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2763 wxString
wxWindow::GetTitle() const
2765 return (wxString
&)m_windowName
;
2768 wxString
wxWindow::GetLabel() const
2773 void wxWindow::SetName( const wxString
&name
)
2775 m_windowName
= name
;
2778 wxString
wxWindow::GetName() const
2780 return (wxString
&)m_windowName
;
2783 bool wxWindow::IsShown() const
2788 bool wxWindow::IsRetained()
2793 wxWindow
*wxWindow::FindWindow( long id
)
2795 if (id
== m_windowId
) return this;
2796 wxNode
*node
= m_children
.First();
2799 wxWindow
*child
= (wxWindow
*)node
->Data();
2800 wxWindow
*res
= child
->FindWindow( id
);
2801 if (res
) return res
;
2802 node
= node
->Next();
2804 return (wxWindow
*) NULL
;
2807 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2809 if (name
== m_windowName
) return this;
2810 wxNode
*node
= m_children
.First();
2813 wxWindow
*child
= (wxWindow
*)node
->Data();
2814 wxWindow
*res
= child
->FindWindow( name
);
2815 if (res
) return res
;
2816 node
= node
->Next();
2818 return (wxWindow
*) NULL
;
2821 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2822 int range
, bool refresh
)
2824 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2826 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2828 m_hasScrolling
= TRUE
;
2830 if (orient
== wxHORIZONTAL
)
2832 float fpos
= (float)pos
;
2833 float frange
= (float)range
;
2834 float fthumb
= (float)thumbVisible
;
2835 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2836 if (fpos
< 0.0) fpos
= 0.0;
2838 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2839 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2841 SetScrollPos( orient
, pos
, refresh
);
2845 m_oldHorizontalPos
= fpos
;
2847 m_hAdjust
->lower
= 0.0;
2848 m_hAdjust
->upper
= frange
;
2849 m_hAdjust
->value
= fpos
;
2850 m_hAdjust
->step_increment
= 1.0;
2851 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2852 m_hAdjust
->page_size
= fthumb
;
2856 float fpos
= (float)pos
;
2857 float frange
= (float)range
;
2858 float fthumb
= (float)thumbVisible
;
2859 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2860 if (fpos
< 0.0) fpos
= 0.0;
2862 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2863 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2865 SetScrollPos( orient
, pos
, refresh
);
2869 m_oldVerticalPos
= fpos
;
2871 m_vAdjust
->lower
= 0.0;
2872 m_vAdjust
->upper
= frange
;
2873 m_vAdjust
->value
= fpos
;
2874 m_vAdjust
->step_increment
= 1.0;
2875 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2876 m_vAdjust
->page_size
= fthumb
;
2879 if (m_wxwindow
->window
)
2881 if (orient
== wxHORIZONTAL
)
2882 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
2884 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
2886 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
2890 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
2892 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2894 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2896 if (orient
== wxHORIZONTAL
)
2898 float fpos
= (float)pos
;
2899 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
2900 if (fpos
< 0.0) fpos
= 0.0;
2901 m_oldHorizontalPos
= fpos
;
2903 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
2904 m_hAdjust
->value
= fpos
;
2908 float fpos
= (float)pos
;
2909 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
2910 if (fpos
< 0.0) fpos
= 0.0;
2911 m_oldVerticalPos
= fpos
;
2913 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
2914 m_vAdjust
->value
= fpos
;
2919 if (m_wxwindow
->window
)
2921 if (orient
== wxHORIZONTAL
)
2922 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
2924 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
2929 int wxWindow::GetScrollThumb( int orient
) const
2931 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2933 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2935 if (orient
== wxHORIZONTAL
)
2936 return (int)(m_hAdjust
->page_size
+0.5);
2938 return (int)(m_vAdjust
->page_size
+0.5);
2941 int wxWindow::GetScrollPos( int orient
) const
2943 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2945 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2947 if (orient
== wxHORIZONTAL
)
2948 return (int)(m_hAdjust
->value
+0.5);
2950 return (int)(m_vAdjust
->value
+0.5);
2953 int wxWindow::GetScrollRange( int orient
) const
2955 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
2957 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
2959 if (orient
== wxHORIZONTAL
)
2960 return (int)(m_hAdjust
->upper
+0.5);
2962 return (int)(m_vAdjust
->upper
+0.5);
2965 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
2967 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2969 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2973 GetClientSize( &cw
, &ch
);
2975 int w
= cw
- abs(dx
);
2976 int h
= ch
- abs(dy
);
2977 if ((h
< 0) || (w
< 0))
2984 if (dx
< 0) s_x
= -dx
;
2985 if (dy
< 0) s_y
= -dy
;
2988 if (dx
> 0) d_x
= dx
;
2989 if (dy
> 0) d_y
= dy
;
2993 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
2994 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
2997 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
2998 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3001 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3002 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3003 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3004 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3006 Refresh( TRUE
, &rect
);
3009 //-------------------------------------------------------------------------------------
3011 //-------------------------------------------------------------------------------------
3013 wxLayoutConstraints
*wxWindow::GetConstraints() const
3015 return m_constraints
;
3018 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3022 UnsetConstraints(m_constraints
);
3023 delete m_constraints
;
3025 m_constraints
= constraints
;
3028 // Make sure other windows know they're part of a 'meaningful relationship'
3029 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3030 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3031 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3032 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3033 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3034 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3035 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3036 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3037 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3038 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3039 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3040 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3041 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3042 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3043 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3044 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3050 void wxWindow::SetAutoLayout( bool autoLayout
)
3052 m_autoLayout
= autoLayout
;
3055 bool wxWindow::GetAutoLayout() const
3057 return m_autoLayout
;
3060 wxSizer
*wxWindow::GetSizer() const
3062 return m_windowSizer
;
3065 void wxWindow::SetSizerParent( wxWindow
*win
)
3067 m_sizerParent
= win
;
3070 wxWindow
*wxWindow::GetSizerParent() const
3072 return m_sizerParent
;
3075 // This removes any dangling pointers to this window
3076 // in other windows' constraintsInvolvedIn lists.
3077 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3081 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3082 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3083 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3084 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3085 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3086 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3087 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3088 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3089 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3090 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3091 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3092 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3093 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3094 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3095 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3096 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3100 // Back-pointer to other windows we're involved with, so if we delete
3101 // this window, we must delete any constraints we're involved with.
3102 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3104 if (!m_constraintsInvolvedIn
)
3105 m_constraintsInvolvedIn
= new wxList
;
3106 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3107 m_constraintsInvolvedIn
->Append(otherWin
);
3110 // REMOVE back-pointer to other windows we're involved with.
3111 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3113 if (m_constraintsInvolvedIn
)
3114 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3117 // Reset any constraints that mention this window
3118 void wxWindow::DeleteRelatedConstraints()
3120 if (m_constraintsInvolvedIn
)
3122 wxNode
*node
= m_constraintsInvolvedIn
->First();
3125 wxWindow
*win
= (wxWindow
*)node
->Data();
3126 wxNode
*next
= node
->Next();
3127 wxLayoutConstraints
*constr
= win
->GetConstraints();
3129 // Reset any constraints involving this window
3132 constr
->left
.ResetIfWin((wxWindow
*)this);
3133 constr
->top
.ResetIfWin((wxWindow
*)this);
3134 constr
->right
.ResetIfWin((wxWindow
*)this);
3135 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3136 constr
->width
.ResetIfWin((wxWindow
*)this);
3137 constr
->height
.ResetIfWin((wxWindow
*)this);
3138 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3139 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3144 delete m_constraintsInvolvedIn
;
3145 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3149 void wxWindow::SetSizer(wxSizer
*sizer
)
3151 m_windowSizer
= sizer
;
3153 sizer
->SetSizerParent((wxWindow
*)this);
3160 bool wxWindow::Layout()
3162 if (GetConstraints())
3165 GetClientSize(&w
, &h
);
3166 GetConstraints()->width
.SetValue(w
);
3167 GetConstraints()->height
.SetValue(h
);
3170 // If top level (one sizer), evaluate the sizer's constraints.
3174 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3175 GetSizer()->LayoutPhase1(&noChanges
);
3176 GetSizer()->LayoutPhase2(&noChanges
);
3177 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3182 // Otherwise, evaluate child constraints
3183 ResetConstraints(); // Mark all constraints as unevaluated
3184 DoPhase(1); // Just one phase need if no sizers involved
3186 SetConstraintSizes(); // Recursively set the real window sizes
3192 // Do a phase of evaluating constraints:
3193 // the default behaviour. wxSizers may do a similar
3194 // thing, but also impose their own 'constraints'
3195 // and order the evaluation differently.
3196 bool wxWindow::LayoutPhase1(int *noChanges
)
3198 wxLayoutConstraints
*constr
= GetConstraints();
3201 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3207 bool wxWindow::LayoutPhase2(int *noChanges
)
3217 // Do a phase of evaluating child constraints
3218 bool wxWindow::DoPhase(int phase
)
3220 int noIterations
= 0;
3221 int maxIterations
= 500;
3225 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3229 wxNode
*node
= m_children
.First();
3232 wxWindow
*child
= (wxWindow
*)node
->Data();
3233 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3235 wxLayoutConstraints
*constr
= child
->GetConstraints();
3238 if (succeeded
.Member(child
))
3243 int tempNoChanges
= 0;
3244 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3245 noChanges
+= tempNoChanges
;
3248 succeeded
.Append(child
);
3253 node
= node
->Next();
3260 void wxWindow::ResetConstraints()
3262 wxLayoutConstraints
*constr
= GetConstraints();
3265 constr
->left
.SetDone(FALSE
);
3266 constr
->top
.SetDone(FALSE
);
3267 constr
->right
.SetDone(FALSE
);
3268 constr
->bottom
.SetDone(FALSE
);
3269 constr
->width
.SetDone(FALSE
);
3270 constr
->height
.SetDone(FALSE
);
3271 constr
->centreX
.SetDone(FALSE
);
3272 constr
->centreY
.SetDone(FALSE
);
3274 wxNode
*node
= m_children
.First();
3277 wxWindow
*win
= (wxWindow
*)node
->Data();
3278 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3279 win
->ResetConstraints();
3280 node
= node
->Next();
3284 // Need to distinguish between setting the 'fake' size for
3285 // windows and sizers, and setting the real values.
3286 void wxWindow::SetConstraintSizes(bool recurse
)
3288 wxLayoutConstraints
*constr
= GetConstraints();
3289 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3290 constr
->width
.GetDone() && constr
->height
.GetDone())
3292 int x
= constr
->left
.GetValue();
3293 int y
= constr
->top
.GetValue();
3294 int w
= constr
->width
.GetValue();
3295 int h
= constr
->height
.GetValue();
3297 // If we don't want to resize this window, just move it...
3298 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3299 (constr
->height
.GetRelationship() != wxAsIs
))
3301 // Calls Layout() recursively. AAAGH. How can we stop that.
3302 // Simply take Layout() out of non-top level OnSizes.
3303 SizerSetSize(x
, y
, w
, h
);
3312 char *windowClass
= this->GetClassInfo()->GetClassName();
3315 if (GetName() == "")
3316 winName
= "unnamed";
3318 winName
= GetName();
3319 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3320 (const char *)windowClass
,
3321 (const char *)winName
);
3322 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3323 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3324 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3325 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3326 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3331 wxNode
*node
= m_children
.First();
3334 wxWindow
*win
= (wxWindow
*)node
->Data();
3335 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3336 win
->SetConstraintSizes();
3337 node
= node
->Next();
3342 // This assumes that all sizers are 'on' the same
3343 // window, i.e. the parent of this window.
3344 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3346 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3347 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3351 m_sizerParent
->GetPosition(&xp
, &yp
);
3352 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3357 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3361 TransformSizerToActual(&xx
, &yy
);
3362 SetSize(xx
, yy
, w
, h
);
3365 void wxWindow::SizerMove(int x
, int y
)
3369 TransformSizerToActual(&xx
, &yy
);
3373 // Only set the size/position of the constraint (if any)
3374 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3376 wxLayoutConstraints
*constr
= GetConstraints();
3381 constr
->left
.SetValue(x
);
3382 constr
->left
.SetDone(TRUE
);
3386 constr
->top
.SetValue(y
);
3387 constr
->top
.SetDone(TRUE
);
3391 constr
->width
.SetValue(w
);
3392 constr
->width
.SetDone(TRUE
);
3396 constr
->height
.SetValue(h
);
3397 constr
->height
.SetDone(TRUE
);
3402 void wxWindow::MoveConstraint(int x
, int y
)
3404 wxLayoutConstraints
*constr
= GetConstraints();
3409 constr
->left
.SetValue(x
);
3410 constr
->left
.SetDone(TRUE
);
3414 constr
->top
.SetValue(y
);
3415 constr
->top
.SetDone(TRUE
);
3420 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3422 wxLayoutConstraints
*constr
= GetConstraints();
3425 *w
= constr
->width
.GetValue();
3426 *h
= constr
->height
.GetValue();
3432 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3434 wxLayoutConstraints
*constr
= GetConstraints();
3437 *w
= constr
->width
.GetValue();
3438 *h
= constr
->height
.GetValue();
3441 GetClientSize(w
, h
);
3444 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3446 wxLayoutConstraints
*constr
= GetConstraints();
3449 *x
= constr
->left
.GetValue();
3450 *y
= constr
->top
.GetValue();