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/tooltip.h"
31 #include "wx/statusbr.h"
33 #include "wx/settings.h"
40 #include "gdk/gdkprivate.h"
41 #include "gdk/gdkkeysyms.h"
42 #include "wx/gtk/win_gtk.h"
44 //-----------------------------------------------------------------------------
45 // documentation on internals
46 //-----------------------------------------------------------------------------
49 I have been asked several times about writing some documentation about
50 the GTK port of wxWindows, especially its internal structures. Obviously,
51 you cannot understand wxGTK without knowing a little about the GTK, but
52 some more information about what the wxWindow, which is the base class
53 for all other window classes, does seems required as well.
55 What does wxWindow do? It contains the common interface for the following
56 jobs of its descendants:
58 1) Define the rudimentary behaviour common to all window classes, such as
59 resizing, intercepting user input (so as to make it possible to use these
60 events for special purposes in a derived class), window names etc.
62 2) Provide the possibility to contain and manage children, if the derived
63 class is allowed to contain children, which holds true for those window
64 classes which do not display a native GTK widget. To name them, these
65 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
66 work classes are a special case and are handled a bit differently from
67 the rest. The same holds true for the wxNotebook class.
69 3) Provide the possibility to draw into a client area of a window. This,
70 too, only holds true for classes that do not display a native GTK widget
73 4) Provide the entire mechanism for scrolling widgets. This actual inter-
74 face for this is usually in wxScrolledWindow, but the GTK implementation
77 5) A multitude of helper or extra methods for special purposes, such as
78 Drag'n'Drop, managing validators etc.
80 Normally one might expect, that one wxWindows window would always correspond
81 to one GTK widget. Under GTK, there is no such allround widget that has all
82 the functionality. Moreover, the GTK defines a client area as a different
83 widget from the actual widget you are handling. Last but not least some
84 special classes (e.g. wxFrame) handle different categories of widgets and
85 still have the possibility to draw something in the client area.
86 It was therefore required to write a special purpose GTK widget, that would
87 represent a client area in the sense of wxWindows capable to do the jobs
88 2), 3) and 4). I have written this class and it resides in win_gtk.c of
91 All windows must have a widget, with which they interact with other under-
92 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
93 thw wxWindow class has a member variable called m_widget which holds a
94 pointer to this widget. When the window class represents a GTK native widget,
95 this is (in most cases) the only GTK widget the class manages. E.g. the
96 wxStatitText class handles only a GtkLabel widget a pointer to which you
97 can find in m_widget (defined in wxWindow)
99 When the class has a client area for drawing into and for containing children
100 it has to handle the client area widget (of the type GtkMyFixed, defined in
101 win_gtk.c), but there could be any number of widgets, handled by a class
102 The common rule for all windows is only, that the widget that interacts with
103 the rest of GTK must be referenced in m_widget and all other widgets must be
104 children of this widget on the GTK level. The top-most widget, which also
105 represents the client area, must be in the m_wxwindow field and must be of
108 As I said, the window classes that display a GTK native widget only have
109 one widget, so in the case of e.g. the wxButton class m_widget holds a
110 pointer to a GtkButton widget. But windows with client areas (for drawing
111 and children) have a m_widget field that is a pointer to a GtkScrolled-
112 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
113 one is (in the GTK sense) a child of the GtkScrolledWindow.
115 If the m_wxwindow field is set, then all input to this widget is inter-
116 cepted and sent to the wxWindows class. If not, all input to the widget
117 that gets pointed to by m_widget gets intercepted and sent to the class.
121 //-------------------------------------------------------------------------
122 // conditional compilation
123 //-------------------------------------------------------------------------
125 #if (GTK_MINOR_VERSION == 1)
126 #if (GTK_MICRO_VERSION >= 5)
127 #define NEW_GTK_SCROLL_CODE
131 //-----------------------------------------------------------------------------
133 //-----------------------------------------------------------------------------
137 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
138 GdkEvent
*WXUNUSED(event
),
141 printf( "FOCUS NOW AT: " );
148 void debug_focus_in( GtkWidget
* widget
, const char* name
, const char *window
)
156 char *s
= new char[tmp
.Length()+1];
158 strcpy( s
, WXSTRINGCAST tmp
);
160 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
161 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
166 //-----------------------------------------------------------------------------
168 //-----------------------------------------------------------------------------
170 extern wxList wxPendingDelete
;
171 extern wxList wxTopLevelWindows
;
172 extern bool g_blockEventsOnDrag
;
173 extern bool g_blockEventsOnScroll
;
174 static bool g_capturing
= FALSE
;
175 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
177 // hack: we need something to pass to gtk_menu_popup, so we store the time of
178 // the last click here
179 static guint32 gs_timeLastClick
= 0;
181 //-----------------------------------------------------------------------------
182 // "expose_event" (of m_wxwindow, not of m_widget)
183 //-----------------------------------------------------------------------------
185 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
187 if (!win
->HasVMT()) return;
189 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
191 gdk_event
->area
.width
,
192 gdk_event
->area
.height
);
194 if (gdk_event
->count
> 0) return;
197 printf( "OnExpose from " );
198 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
199 printf( win->GetClassInfo()->GetClassName() );
203 wxPaintEvent
event( win
->GetId() );
204 event
.SetEventObject( win
);
205 win
->GetEventHandler()->ProcessEvent( event
);
207 win
->m_updateRegion
.Clear();
210 //-----------------------------------------------------------------------------
211 // "draw" (of m_wxwindow, not of m_widget)
212 //-----------------------------------------------------------------------------
214 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
216 if (!win
->HasVMT()) return;
218 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
220 wxPaintEvent
event( win
->GetId() );
221 event
.SetEventObject( win
);
222 win
->GetEventHandler()->ProcessEvent( event
);
224 win
->m_updateRegion
.Clear();
227 //-----------------------------------------------------------------------------
228 // "key_press_event" from any window
229 //-----------------------------------------------------------------------------
231 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
233 if (!win
->HasVMT()) return FALSE
;
234 if (g_blockEventsOnDrag
) return FALSE
;
237 printf( "OnKeyPress from " );
238 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
239 printf( win->GetClassInfo()->GetClassName() );
244 switch (gdk_event
->keyval
)
246 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
247 case GDK_Tab
: key_code
= WXK_TAB
; break;
248 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
249 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
250 case GDK_Return
: key_code
= WXK_RETURN
; break;
251 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
252 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
253 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
254 case GDK_Delete
: key_code
= WXK_DELETE
; break;
255 case GDK_Home
: key_code
= WXK_HOME
; break;
256 case GDK_Left
: key_code
= WXK_LEFT
; break;
257 case GDK_Up
: key_code
= WXK_UP
; break;
258 case GDK_Right
: key_code
= WXK_RIGHT
; break;
259 case GDK_Down
: key_code
= WXK_DOWN
; break;
260 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
261 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
262 case GDK_Next
: key_code
= WXK_NEXT
; break;
263 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
264 case GDK_End
: key_code
= WXK_END
; break;
265 case GDK_Begin
: key_code
= WXK_HOME
; break;
266 case GDK_Select
: key_code
= WXK_SELECT
; break;
267 case GDK_Print
: key_code
= WXK_PRINT
; break;
268 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
269 case GDK_Insert
: key_code
= WXK_INSERT
; break;
270 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
271 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
272 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
273 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
274 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
275 case GDK_KP_Up
: key_code
= WXK_UP
; break;
276 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
277 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
278 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
279 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
280 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
281 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
282 case GDK_KP_End
: key_code
= WXK_END
; break;
283 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
284 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
285 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
286 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
287 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
288 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
289 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
290 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
291 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
292 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
293 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
294 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
295 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
296 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
297 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
298 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
299 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
300 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
301 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
302 case GDK_F1
: key_code
= WXK_F1
; break;
303 case GDK_F2
: key_code
= WXK_F2
; break;
304 case GDK_F3
: key_code
= WXK_F3
; break;
305 case GDK_F4
: key_code
= WXK_F4
; break;
306 case GDK_F5
: key_code
= WXK_F5
; break;
307 case GDK_F6
: key_code
= WXK_F6
; break;
308 case GDK_F7
: key_code
= WXK_F7
; break;
309 case GDK_F8
: key_code
= WXK_F8
; break;
310 case GDK_F9
: key_code
= WXK_F9
; break;
311 case GDK_F10
: key_code
= WXK_F10
; break;
312 case GDK_F11
: key_code
= WXK_F11
; break;
313 case GDK_F12
: key_code
= WXK_F12
; break;
316 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
317 key_code
= gdk_event
->keyval
;
321 if (!key_code
) return FALSE
;
323 wxKeyEvent
event( wxEVT_KEY_DOWN
);
324 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
325 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
326 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
327 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
328 event
.m_keyCode
= key_code
;
331 event
.SetEventObject( win
);
333 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
337 wxWindow
*ancestor
= win
;
340 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
343 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
344 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
347 ancestor
= ancestor
->GetParent();
351 // win is a control: tab can be propagated up
352 if ((!ret
) && (gdk_event
->keyval
== GDK_Tab
) && ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
354 wxNavigationKeyEvent new_event
;
355 new_event
.SetDirection( !(gdk_event
->state
& GDK_SHIFT_MASK
) );
356 new_event
.SetWindowChange( FALSE
);
357 new_event
.SetCurrentFocus( win
);
358 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
362 // win is a panel: up can be propagated to the panel
363 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
364 (gdk_event->keyval == GDK_Up))
366 win->m_parent->SetFocus();
370 // win is a panel: left/right can be propagated to the panel
371 if ((!ret) && (win->m_wxwindow) &&
372 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
373 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
375 wxNavigationKeyEvent new_event;
376 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
377 new_event.SetCurrentFocus( win );
378 ret = win->GetEventHandler()->ProcessEvent( new_event );
384 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
390 //-----------------------------------------------------------------------------
391 // "key_release_event" from any window
392 //-----------------------------------------------------------------------------
394 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
396 if (!win
->HasVMT()) return FALSE
;
397 if (g_blockEventsOnDrag
) return FALSE
;
400 printf( "OnKeyRelease from " );
401 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
402 printf( win->GetClassInfo()->GetClassName() );
407 switch (gdk_event
->keyval
)
409 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
410 case GDK_Tab
: key_code
= WXK_TAB
; break;
411 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
412 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
413 case GDK_Return
: key_code
= WXK_RETURN
; break;
414 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
415 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
416 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
417 case GDK_Delete
: key_code
= WXK_DELETE
; break;
418 case GDK_Home
: key_code
= WXK_HOME
; break;
419 case GDK_Left
: key_code
= WXK_LEFT
; break;
420 case GDK_Up
: key_code
= WXK_UP
; break;
421 case GDK_Right
: key_code
= WXK_RIGHT
; break;
422 case GDK_Down
: key_code
= WXK_DOWN
; break;
423 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
424 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
425 case GDK_Next
: key_code
= WXK_NEXT
; break;
426 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
427 case GDK_End
: key_code
= WXK_END
; break;
428 case GDK_Begin
: key_code
= WXK_HOME
; break;
429 case GDK_Select
: key_code
= WXK_SELECT
; break;
430 case GDK_Print
: key_code
= WXK_PRINT
; break;
431 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
432 case GDK_Insert
: key_code
= WXK_INSERT
; break;
433 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
434 case GDK_KP_Tab
: key_code
= WXK_TAB
; break;
435 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
436 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
437 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
438 case GDK_KP_Up
: key_code
= WXK_UP
; break;
439 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
440 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
441 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
442 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
443 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
444 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
445 case GDK_KP_End
: key_code
= WXK_END
; break;
446 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
447 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
448 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
449 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
450 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
451 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
452 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
453 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
454 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
455 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
456 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
457 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
458 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
459 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
460 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
461 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
462 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
463 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
464 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
465 case GDK_F1
: key_code
= WXK_F1
; break;
466 case GDK_F2
: key_code
= WXK_F2
; break;
467 case GDK_F3
: key_code
= WXK_F3
; break;
468 case GDK_F4
: key_code
= WXK_F4
; break;
469 case GDK_F5
: key_code
= WXK_F5
; break;
470 case GDK_F6
: key_code
= WXK_F6
; break;
471 case GDK_F7
: key_code
= WXK_F7
; break;
472 case GDK_F8
: key_code
= WXK_F8
; break;
473 case GDK_F9
: key_code
= WXK_F9
; break;
474 case GDK_F10
: key_code
= WXK_F10
; break;
475 case GDK_F11
: key_code
= WXK_F11
; break;
476 case GDK_F12
: key_code
= WXK_F12
; break;
479 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
480 key_code
= gdk_event
->keyval
;
484 if (!key_code
) return FALSE
;
486 wxKeyEvent
event( wxEVT_KEY_UP
);
487 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
488 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
489 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
490 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
491 event
.m_keyCode
= key_code
;
494 event
.SetEventObject( win
);
496 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
500 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
506 //-----------------------------------------------------------------------------
507 // "button_press_event"
508 //-----------------------------------------------------------------------------
510 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
512 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
514 if (g_blockEventsOnDrag
) return TRUE
;
515 if (g_blockEventsOnScroll
) return TRUE
;
519 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
521 gtk_widget_grab_focus (win
->m_wxwindow
);
524 printf( "GrabFocus from " );
525 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
526 printf( win->GetClassInfo()->GetClassName() );
533 if (!win
->HasVMT()) return TRUE
;
536 printf( "OnButtonPress from " );
537 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
538 printf( win->GetClassInfo()->GetClassName() );
542 wxEventType event_type
= wxEVT_LEFT_DOWN
;
544 if (gdk_event
->button
== 1)
546 switch (gdk_event
->type
)
548 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
549 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
553 else if (gdk_event
->button
== 2)
555 switch (gdk_event
->type
)
557 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
558 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
562 else if (gdk_event
->button
== 3)
564 switch (gdk_event
->type
)
566 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
567 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
572 wxMouseEvent
event( event_type
);
573 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
574 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
575 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
576 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
577 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
578 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
579 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
581 event
.m_x
= (long)gdk_event
->x
;
582 event
.m_y
= (long)gdk_event
->y
;
584 // Some control don't have their own X window and thus cannot get
589 wxNode
*node
= win
->GetChildren().First();
592 wxWindow
*child
= (wxWindow
*)node
->Data();
594 if (child
->m_isStaticBox
)
596 // wxStaticBox is transparent in the box itself
599 int xx1
= child
->m_x
;
600 int yy1
= child
->m_y
;
601 int xx2
= child
->m_x
+ child
->m_width
;
602 int yy2
= child
->m_x
+ child
->m_height
;
605 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
607 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
609 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
611 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
614 event
.m_x
-= child
->m_x
;
615 event
.m_y
-= child
->m_y
;
622 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
623 (child
->m_x
<= event
.m_x
) &&
624 (child
->m_y
<= event
.m_y
) &&
625 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
626 (child
->m_y
+child
->m_height
>= event
.m_y
))
629 event
.m_x
-= child
->m_x
;
630 event
.m_y
-= child
->m_y
;
638 wxPoint
pt(win
->GetClientAreaOrigin());
642 event
.SetEventObject( win
);
644 gs_timeLastClick
= gdk_event
->time
;
646 if (win
->GetEventHandler()->ProcessEvent( event
))
647 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
652 //-----------------------------------------------------------------------------
653 // "button_release_event"
654 //-----------------------------------------------------------------------------
656 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
658 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
660 if (g_blockEventsOnDrag
) return TRUE
;
661 if (g_blockEventsOnScroll
) return TRUE
;
663 if (!win
->HasVMT()) return TRUE
;
666 printf( "OnButtonRelease from " );
667 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
668 printf( win->GetClassInfo()->GetClassName() );
672 wxEventType event_type
= wxEVT_NULL
;
674 switch (gdk_event
->button
)
676 case 1: event_type
= wxEVT_LEFT_UP
; break;
677 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
678 case 3: event_type
= wxEVT_RIGHT_UP
; break;
681 wxMouseEvent
event( event_type
);
682 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
683 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
684 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
685 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
686 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
687 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
688 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
689 event
.m_x
= (long)gdk_event
->x
;
690 event
.m_y
= (long)gdk_event
->y
;
692 // Some control don't have their own X window and thus cannot get
697 wxNode
*node
= win
->GetChildren().First();
700 wxWindow
*child
= (wxWindow
*)node
->Data();
702 if (child
->m_isStaticBox
)
704 // wxStaticBox is transparent in the box itself
707 int xx1
= child
->m_x
;
708 int yy1
= child
->m_y
;
709 int xx2
= child
->m_x
+ child
->m_width
;
710 int yy2
= child
->m_x
+ child
->m_height
;
713 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
715 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
717 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
719 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
722 event
.m_x
-= child
->m_x
;
723 event
.m_y
-= child
->m_y
;
730 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
731 (child
->m_x
<= event
.m_x
) &&
732 (child
->m_y
<= event
.m_y
) &&
733 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
734 (child
->m_y
+child
->m_height
>= event
.m_y
))
737 event
.m_x
-= child
->m_x
;
738 event
.m_y
-= child
->m_y
;
746 wxPoint
pt(win
->GetClientAreaOrigin());
750 event
.SetEventObject( win
);
752 if (win
->GetEventHandler()->ProcessEvent( event
))
753 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
758 //-----------------------------------------------------------------------------
759 // "motion_notify_event"
760 //-----------------------------------------------------------------------------
762 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
764 if (gdk_event
->is_hint
)
768 GdkModifierType state
;
769 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
772 gdk_event
->state
= state
;
775 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
777 if (g_blockEventsOnDrag
) return TRUE
;
778 if (g_blockEventsOnScroll
) return TRUE
;
780 if (!win
->HasVMT()) return TRUE
;
783 printf( "OnMotion from " );
784 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
785 printf( win->GetClassInfo()->GetClassName() );
789 wxMouseEvent
event( wxEVT_MOTION
);
790 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
791 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
792 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
793 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
794 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
795 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
796 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
798 event
.m_x
= (long)gdk_event
->x
;
799 event
.m_y
= (long)gdk_event
->y
;
801 // Some control don't have their own X window and thus cannot get
806 wxNode
*node
= win
->GetChildren().First();
809 wxWindow
*child
= (wxWindow
*)node
->Data();
811 if (child
->m_isStaticBox
)
813 // wxStaticBox is transparent in the box itself
816 int xx1
= child
->m_x
;
817 int yy1
= child
->m_y
;
818 int xx2
= child
->m_x
+ child
->m_width
;
819 int yy2
= child
->m_x
+ child
->m_height
;
822 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
824 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
826 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
828 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
831 event
.m_x
-= child
->m_x
;
832 event
.m_y
-= child
->m_y
;
839 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
840 (child
->m_x
<= event
.m_x
) &&
841 (child
->m_y
<= event
.m_y
) &&
842 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
843 (child
->m_y
+child
->m_height
>= event
.m_y
))
846 event
.m_x
-= child
->m_x
;
847 event
.m_y
-= child
->m_y
;
855 wxPoint
pt(win
->GetClientAreaOrigin());
859 event
.SetEventObject( win
);
861 if (win
->GetEventHandler()->ProcessEvent( event
))
862 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
867 //-----------------------------------------------------------------------------
869 //-----------------------------------------------------------------------------
871 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
873 if (g_blockEventsOnDrag
) return TRUE
;
879 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
881 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
883 printf( "SetFocus flag from " );
884 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
885 printf( win->GetClassInfo()->GetClassName() );
891 if (!win
->HasVMT()) return TRUE
;
894 printf( "OnSetFocus from " );
895 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
896 printf( win->GetClassInfo()->GetClassName() );
898 printf( WXSTRINGCAST win->GetLabel() );
902 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
903 event
.SetEventObject( win
);
905 if (win
->GetEventHandler()->ProcessEvent( event
))
906 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
911 //-----------------------------------------------------------------------------
913 //-----------------------------------------------------------------------------
915 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
917 if (g_blockEventsOnDrag
) return TRUE
;
920 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
921 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
924 if (!win
->HasVMT()) return TRUE
;
927 printf( "OnKillFocus from " );
928 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
929 printf( win->GetClassInfo()->GetClassName() );
933 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
934 event
.SetEventObject( win
);
936 if (win
->GetEventHandler()->ProcessEvent( event
))
937 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
942 //-----------------------------------------------------------------------------
943 // "enter_notify_event"
944 //-----------------------------------------------------------------------------
946 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
948 if (g_blockEventsOnDrag
) return TRUE
;
950 if ((widget
->window
) && (win
->m_cursor
))
951 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
953 if (widget
->window
!= gdk_event
->window
) return TRUE
;
955 if (!win
->HasVMT()) return TRUE
;
958 printf( "OnEnter from " );
959 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
960 printf( win->GetClassInfo()->GetClassName() );
964 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
965 event
.SetEventObject( win
);
969 GdkModifierType state
= (GdkModifierType
)0;
971 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
973 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
974 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
975 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
976 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
977 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
978 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
979 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
984 wxPoint
pt(win
->GetClientAreaOrigin());
988 if (win
->GetEventHandler()->ProcessEvent( event
))
989 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
994 //-----------------------------------------------------------------------------
995 // "leave_notify_event"
996 //-----------------------------------------------------------------------------
998 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1000 if (g_blockEventsOnDrag
) return TRUE
;
1002 if ((widget
->window
) && (win
->m_cursor
))
1003 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1005 if (widget
->window
!= gdk_event
->window
) return TRUE
;
1007 if (!win
->HasVMT()) return TRUE
;
1010 printf( "OnLeave from " );
1011 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1012 printf( win->GetClassInfo()->GetClassName() );
1016 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1017 event
.SetEventObject( win
);
1021 GdkModifierType state
= (GdkModifierType
)0;
1023 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1025 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1026 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1027 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1028 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1029 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1030 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1031 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1033 event
.m_x
= (long)x
;
1034 event
.m_y
= (long)y
;
1036 wxPoint
pt(win
->GetClientAreaOrigin());
1040 if (win
->GetEventHandler()->ProcessEvent( event
))
1041 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1046 //-----------------------------------------------------------------------------
1047 // "value_changed" from m_vAdjust
1048 //-----------------------------------------------------------------------------
1050 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1052 if (g_blockEventsOnDrag
) return;
1055 printf( "OnVScroll from " );
1056 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1057 printf( win->GetClassInfo()->GetClassName() );
1061 if (!win
->HasVMT()) return;
1063 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1064 if (fabs(diff
) < 0.2) return;
1066 wxEventType command
= wxEVT_NULL
;
1068 float line_step
= win
->m_vAdjust
->step_increment
;
1069 float page_step
= win
->m_vAdjust
->page_increment
;
1071 if (win
->m_isScrolling
)
1073 command
= wxEVT_SCROLL_THUMBTRACK
;
1077 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1078 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1079 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1080 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1081 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1082 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1083 else command
= wxEVT_SCROLL_THUMBTRACK
;
1086 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1088 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1089 event
.SetEventObject( win
);
1090 win
->GetEventHandler()->ProcessEvent( event
);
1093 //-----------------------------------------------------------------------------
1094 // "value_changed" from m_hAdjust
1095 //-----------------------------------------------------------------------------
1097 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1099 if (g_blockEventsOnDrag
) return;
1102 printf( "OnHScroll from " );
1103 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1104 printf( win->GetClassInfo()->GetClassName() );
1108 if (!win
->HasVMT()) return;
1110 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1111 if (fabs(diff
) < 0.2) return;
1113 wxEventType command
= wxEVT_NULL
;
1115 float line_step
= win
->m_hAdjust
->step_increment
;
1116 float page_step
= win
->m_hAdjust
->page_increment
;
1118 if (win
->m_isScrolling
)
1120 command
= wxEVT_SCROLL_THUMBTRACK
;
1124 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1125 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1126 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1127 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1128 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1129 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1130 else command
= wxEVT_SCROLL_THUMBTRACK
;
1133 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1135 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1136 event
.SetEventObject( win
);
1137 win
->GetEventHandler()->ProcessEvent( event
);
1140 //-----------------------------------------------------------------------------
1141 // "changed" from m_vAdjust
1142 //-----------------------------------------------------------------------------
1144 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1146 if (g_blockEventsOnDrag
) return;
1149 printf( "OnVScroll change from " );
1150 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1151 printf( win->GetClassInfo()->GetClassName() );
1155 if (!win
->HasVMT()) return;
1157 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1158 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1160 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1161 event
.SetEventObject( win
);
1162 win
->GetEventHandler()->ProcessEvent( event
);
1165 //-----------------------------------------------------------------------------
1166 // "changed" from m_hAdjust
1167 //-----------------------------------------------------------------------------
1169 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1171 if (g_blockEventsOnDrag
) return;
1174 printf( "OnHScroll change from " );
1175 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1176 printf( win->GetClassInfo()->GetClassName() );
1180 if (!win
->HasVMT()) return;
1182 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1183 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1185 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1186 event
.SetEventObject( win
);
1187 win
->GetEventHandler()->ProcessEvent( event
);
1190 //-----------------------------------------------------------------------------
1191 // "button_press_event" from scrollbar
1192 //-----------------------------------------------------------------------------
1194 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1195 GdkEventButton
*WXUNUSED(gdk_event
),
1198 // don't test here as we can release the mouse while being over
1199 // a different window then the slider
1201 // if (gdk_event->window != widget->slider) return FALSE;
1203 win
->m_isScrolling
= TRUE
;
1204 g_blockEventsOnScroll
= TRUE
;
1209 //-----------------------------------------------------------------------------
1210 // "button_release_event" from scrollbar
1211 //-----------------------------------------------------------------------------
1213 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1214 GdkEventButton
*WXUNUSED(gdk_event
),
1218 // don't test here as we can release the mouse while being over
1219 // a different window then the slider
1221 // if (gdk_event->window != widget->slider) return FALSE;
1223 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1225 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1226 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1228 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1230 win
->m_isScrolling
= FALSE
;
1231 g_blockEventsOnScroll
= FALSE
;
1236 //-----------------------------------------------------------------------------
1237 // InsertChild for wxWindow.
1238 //-----------------------------------------------------------------------------
1240 /* Callback for wxWindow. This very strange beast has to be used because
1241 * C++ has no virtual methods in a constructor. We have to emulate a
1242 * virtual function here as wxNotebook requires a different way to insert
1243 * a child in it. I had opted for creating a wxNotebookPage window class
1244 * which would have made this superfluous (such in the MDI window system),
1245 * but no-one was listening to me... */
1247 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1249 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1250 GTK_WIDGET(child
->m_widget
),
1254 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1258 if (wxIS_KIND_OF(parent
,wxFrame
))
1260 parent
->m_sizeSet
= FALSE
;
1263 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1265 /* we now allow a window to get the focus as long as it
1266 doesn't have any children. */
1267 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1271 //-----------------------------------------------------------------------------
1273 //-----------------------------------------------------------------------------
1275 wxWindow
* wxGetActiveWindow()
1277 return g_focusWindow
;
1280 //-----------------------------------------------------------------------------
1282 //-----------------------------------------------------------------------------
1284 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1286 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1287 EVT_SIZE(wxWindow::OnSize
)
1288 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1289 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1290 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1293 wxWindow::wxWindow()
1295 m_widget
= (GtkWidget
*) NULL
;
1296 m_wxwindow
= (GtkWidget
*) NULL
;
1297 m_parent
= (wxWindow
*) NULL
;
1298 m_children
.DeleteContents( FALSE
);
1311 m_eventHandler
= this;
1312 m_windowValidator
= (wxValidator
*) NULL
;
1316 m_cursor
= (wxCursor
*) NULL
;
1317 m_font
= *wxSWISS_FONT
;
1319 m_windowName
= "noname";
1321 m_constraints
= (wxLayoutConstraints
*) NULL
;
1322 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1323 m_windowSizer
= (wxSizer
*) NULL
;
1324 m_sizerParent
= (wxWindow
*) NULL
;
1325 m_autoLayout
= FALSE
;
1329 m_needParent
= TRUE
;
1331 m_hasScrolling
= FALSE
;
1332 m_isScrolling
= FALSE
;
1333 m_hAdjust
= (GtkAdjustment
*) NULL
;
1334 m_vAdjust
= (GtkAdjustment
*) NULL
;
1335 m_oldHorizontalPos
= 0.0;
1336 m_oldVerticalPos
= 0.0;
1341 #if wxUSE_DRAG_AND_DROP
1342 m_dropTarget
= (wxDropTarget
*) NULL
;
1345 m_scrollGC
= (GdkGC
*) NULL
;
1346 m_widgetStyle
= (GtkStyle
*) NULL
;
1348 m_insertCallback
= wxInsertChildInWindow
;
1350 m_clientObject
= (wxClientData
*) NULL
;
1351 m_clientData
= NULL
;
1353 m_isStaticBox
= FALSE
;
1354 m_acceptsFocus
= FALSE
;
1357 m_toolTip
= (wxToolTip
*) NULL
;
1358 #endif // wxUSE_TOOLTIPS
1361 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1362 const wxPoint
&pos
, const wxSize
&size
,
1363 long style
, const wxString
&name
)
1365 m_insertCallback
= wxInsertChildInWindow
;
1366 Create( parent
, id
, pos
, size
, style
, name
);
1369 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1370 const wxPoint
&pos
, const wxSize
&size
,
1371 long style
, const wxString
&name
)
1375 m_needParent
= TRUE
;
1377 PreCreation( parent
, id
, pos
, size
, style
, name
);
1379 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1380 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1383 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1386 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1389 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1390 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1393 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1394 scroll_class
->scrollbar_spacing
= 0;
1396 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1398 m_oldHorizontalPos
= 0.0;
1399 m_oldVerticalPos
= 0.0;
1401 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1402 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1404 m_wxwindow
= gtk_myfixed_new();
1407 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1410 #ifdef NEW_GTK_SCROLL_CODE
1411 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1412 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1414 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1415 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1419 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1422 if (m_windowStyle
& wxRAISED_BORDER
)
1424 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1426 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1428 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1432 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1435 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1437 /* we now allow a window to get the focus as long as it
1438 doesn't have any children. */
1439 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1440 m_acceptsFocus
= FALSE
;
1444 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1445 m_acceptsFocus
= TRUE
;
1448 // shut the viewport up
1449 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1450 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1452 // I _really_ don't want scrollbars in the beginning
1453 m_vAdjust
->lower
= 0.0;
1454 m_vAdjust
->upper
= 1.0;
1455 m_vAdjust
->value
= 0.0;
1456 m_vAdjust
->step_increment
= 1.0;
1457 m_vAdjust
->page_increment
= 1.0;
1458 m_vAdjust
->page_size
= 5.0;
1459 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1460 m_hAdjust
->lower
= 0.0;
1461 m_hAdjust
->upper
= 1.0;
1462 m_hAdjust
->value
= 0.0;
1463 m_hAdjust
->step_increment
= 1.0;
1464 m_hAdjust
->page_increment
= 1.0;
1465 m_hAdjust
->page_size
= 5.0;
1466 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1468 // these handlers block mouse events to any window during scrolling
1469 // such as motion events and prevent GTK and wxWindows from fighting
1470 // over where the slider should be
1472 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1473 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1475 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1476 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1478 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1479 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1481 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1482 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1484 // these handers het notified when screen updates are required either when
1485 // scrolling or when the window size (and therefore scrollbar configuration)
1488 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1489 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1490 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1491 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1493 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1494 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1495 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1496 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1498 gtk_widget_show( m_wxwindow
);
1500 if (m_parent
) m_parent
->AddChild( this );
1502 (m_parent
->m_insertCallback
)( m_parent
, this );
1511 wxWindow::~wxWindow()
1513 // Remove potential dangling pointer
1514 if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel
)))
1516 wxPanel
* panel
= (wxPanel
*) GetParent();
1517 if (panel
->GetLastFocus() == this)
1518 panel
->SetLastFocus((wxWindow
*) NULL
);
1523 #if wxUSE_DRAG_AND_DROP
1524 wxDELETE(m_dropTarget
);
1528 wxDELETE(m_toolTip
);
1529 #endif // wxUSE_TOOLTIPS
1531 if (m_parent
) m_parent
->RemoveChild( this );
1532 if (m_widget
) Show( FALSE
);
1536 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1538 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1540 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1542 if (m_widget
) gtk_widget_destroy( m_widget
);
1544 if (m_cursor
) delete m_cursor
;
1546 DeleteRelatedConstraints();
1549 // This removes any dangling pointers to this window
1550 // in other windows' constraintsInvolvedIn lists.
1551 UnsetConstraints(m_constraints
);
1552 delete m_constraints
;
1553 m_constraints
= (wxLayoutConstraints
*) NULL
;
1557 delete m_windowSizer
;
1558 m_windowSizer
= (wxSizer
*) NULL
;
1560 // If this is a child of a sizer, remove self from parent
1561 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1563 // Just in case the window has been Closed, but
1564 // we're then deleting immediately: don't leave
1565 // dangling pointers.
1566 wxPendingDelete
.DeleteObject(this);
1568 // Just in case we've loaded a top-level window via
1569 // wxWindow::LoadNativeDialog but we weren't a dialog
1571 wxTopLevelWindows
.DeleteObject(this);
1573 if (m_windowValidator
) delete m_windowValidator
;
1575 if (m_clientObject
) delete m_clientObject
;
1578 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1579 const wxPoint
&pos
, const wxSize
&size
,
1580 long style
, const wxString
&name
)
1582 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1584 m_widget
= (GtkWidget
*) NULL
;
1585 m_wxwindow
= (GtkWidget
*) NULL
;
1588 m_children
.DeleteContents( FALSE
);
1591 if (m_width
== -1) m_width
= 20;
1593 if (m_height
== -1) m_height
= 20;
1598 if (!m_needParent
) // some reasonable defaults
1602 m_x
= (gdk_screen_width () - m_width
) / 2;
1603 if (m_x
< 10) m_x
= 10;
1607 m_y
= (gdk_screen_height () - m_height
) / 2;
1608 if (m_y
< 10) m_y
= 10;
1619 m_eventHandler
= this;
1621 m_windowId
= id
== -1 ? wxNewId() : id
;
1625 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1626 m_font
= *wxSWISS_FONT
;
1627 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1628 m_foregroundColour
= *wxBLACK
;
1629 m_windowStyle
= style
;
1630 m_windowName
= name
;
1632 m_constraints
= (wxLayoutConstraints
*) NULL
;
1633 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1634 m_windowSizer
= (wxSizer
*) NULL
;
1635 m_sizerParent
= (wxWindow
*) NULL
;
1636 m_autoLayout
= FALSE
;
1638 m_hasScrolling
= FALSE
;
1639 m_isScrolling
= FALSE
;
1640 m_hAdjust
= (GtkAdjustment
*) NULL
;
1641 m_vAdjust
= (GtkAdjustment
*) NULL
;
1642 m_oldHorizontalPos
= 0.0;
1643 m_oldVerticalPos
= 0.0;
1648 #if wxUSE_DRAG_AND_DROP
1649 m_dropTarget
= (wxDropTarget
*) NULL
;
1652 m_windowValidator
= (wxValidator
*) NULL
;
1653 m_scrollGC
= (GdkGC
*) NULL
;
1654 m_widgetStyle
= (GtkStyle
*) NULL
;
1656 m_clientObject
= (wxClientData
*)NULL
;
1657 m_clientData
= NULL
;
1659 m_isStaticBox
= FALSE
;
1662 m_toolTip
= (wxToolTip
*) NULL
;
1663 #endif // wxUSE_TOOLTIPS
1666 void wxWindow::PostCreation()
1670 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1671 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1673 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1674 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1677 ConnectWidget( GetConnectWidget() );
1679 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1681 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1683 SetCursor( *wxSTANDARD_CURSOR
);
1688 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1690 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1691 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1693 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1694 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1696 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1697 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1699 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1700 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1702 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1703 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1705 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1706 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1708 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1709 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1711 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1712 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1714 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1715 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1718 bool wxWindow::HasVMT()
1723 bool wxWindow::Close( bool force
)
1725 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1727 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1728 event
.SetEventObject(this);
1729 event
.SetCanVeto(!force
);
1731 // return FALSE if window wasn't closed because the application vetoed the
1733 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1736 bool wxWindow::Destroy()
1738 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1745 bool wxWindow::DestroyChildren()
1748 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1751 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1754 if (m_children
.Member(child
)) delete node
;
1760 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1762 // are we to set fonts here ?
1765 wxPoint
wxWindow::GetClientAreaOrigin() const
1767 return wxPoint(0,0);
1770 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1772 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1774 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1780 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1782 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1783 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1785 if (m_resizing
) return; // I don't like recursions
1788 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1790 // don't set the size for children of wxNotebook, just take the values.
1798 int old_width
= m_width
;
1799 int old_height
= m_height
;
1801 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1803 if (x
!= -1) m_x
= x
;
1804 if (y
!= -1) m_y
= y
;
1805 if (width
!= -1) m_width
= width
;
1806 if (height
!= -1) m_height
= height
;
1816 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1818 if (width
== -1) m_width
= 80;
1821 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1823 if (height
== -1) m_height
= 26;
1826 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1827 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1828 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1829 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1831 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1833 /* the default button has a border around it */
1836 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1837 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border
);
1839 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1843 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1844 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1846 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1847 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1853 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1854 event
.SetEventObject( this );
1855 GetEventHandler()->ProcessEvent( event
);
1860 void wxWindow::OnInternalIdle()
1865 void wxWindow::SetSize( int width
, int height
)
1867 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1870 void wxWindow::Move( int x
, int y
)
1872 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1875 void wxWindow::GetSize( int *width
, int *height
) const
1877 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1879 if (width
) (*width
) = m_width
;
1880 if (height
) (*height
) = m_height
;
1883 void wxWindow::SetClientSize( int width
, int height
)
1885 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1889 SetSize( width
, height
);
1896 if (!m_hasScrolling
)
1898 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1900 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1901 (m_windowStyle
& wxSUNKEN_BORDER
))
1903 dw
+= 2 * window_class
->xthickness
;
1904 dh
+= 2 * window_class
->ythickness
;
1909 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1910 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1912 #ifdef NEW_GTK_SCROLL_CODE
1913 GtkWidget
*viewport
= scroll_window
->child
;
1915 GtkWidget
*viewport
= scroll_window
->viewport
;
1918 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1920 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1921 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1923 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1924 (m_windowStyle
& wxSUNKEN_BORDER
))
1926 dw
+= 2 * viewport_class
->xthickness
;
1927 dh
+= 2 * viewport_class
->ythickness
;
1930 if (scroll_window
->vscrollbar_visible
)
1932 dw
+= vscrollbar
->allocation
.width
;
1933 dw
+= scroll_class
->scrollbar_spacing
;
1936 if (scroll_window
->hscrollbar_visible
)
1938 dh
+= hscrollbar
->allocation
.height
;
1939 dw
+= scroll_class
->scrollbar_spacing
;
1943 SetSize( width
+dw
, height
+dh
);
1947 void wxWindow::GetClientSize( int *width
, int *height
) const
1949 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1953 if (width
) (*width
) = m_width
;
1954 if (height
) (*height
) = m_height
;
1961 if (!m_hasScrolling
)
1963 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1965 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1966 (m_windowStyle
& wxSUNKEN_BORDER
))
1968 dw
+= 2 * window_class
->xthickness
;
1969 dh
+= 2 * window_class
->ythickness
;
1974 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1975 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1977 #ifdef NEW_GTK_SCROLL_CODE
1978 GtkWidget
*viewport
= scroll_window
->child
;
1980 GtkWidget
*viewport
= scroll_window
->viewport
;
1983 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1985 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1986 (m_windowStyle
& wxSUNKEN_BORDER
))
1988 dw
+= 2 * viewport_class
->xthickness
;
1989 dh
+= 2 * viewport_class
->ythickness
;
1992 if (scroll_window
->vscrollbar_visible
)
1994 // dw += vscrollbar->allocation.width;
1995 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
1996 dw
+= scroll_class
->scrollbar_spacing
;
1999 if (scroll_window
->hscrollbar_visible
)
2001 // dh += hscrollbar->allocation.height;
2003 dh
+= scroll_class
->scrollbar_spacing
;
2007 if (width
) (*width
) = m_width
- dw
;
2008 if (height
) (*height
) = m_height
- dh
;
2012 void wxWindow::GetPosition( int *x
, int *y
) const
2014 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2020 void wxWindow::ClientToScreen( int *x
, int *y
)
2022 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2024 GdkWindow
*source
= (GdkWindow
*) NULL
;
2026 source
= m_wxwindow
->window
;
2028 source
= m_widget
->window
;
2032 gdk_window_get_origin( source
, &org_x
, &org_y
);
2036 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2038 org_x
+= m_widget
->allocation
.x
;
2039 org_y
+= m_widget
->allocation
.y
;
2043 wxPoint
pt(GetClientAreaOrigin());
2051 void wxWindow::ScreenToClient( int *x
, int *y
)
2053 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2055 GdkWindow
*source
= (GdkWindow
*) NULL
;
2057 source
= m_wxwindow
->window
;
2059 source
= m_widget
->window
;
2063 gdk_window_get_origin( source
, &org_x
, &org_y
);
2067 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2069 org_x
+= m_widget
->allocation
.x
;
2070 org_y
+= m_widget
->allocation
.y
;
2074 wxPoint
pt(GetClientAreaOrigin());
2082 void wxWindow::Centre( int direction
)
2084 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2093 m_parent
->GetSize( &p_w
, &p_h
);
2094 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2095 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2099 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2100 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2106 void wxWindow::Fit()
2108 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2112 wxNode
*node
= m_children
.First();
2115 wxWindow
*win
= (wxWindow
*)node
->Data();
2117 win
->GetPosition(&wx
, &wy
);
2118 win
->GetSize(&ww
, &wh
);
2119 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2120 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2122 node
= node
->Next();
2125 SetClientSize(maxX
+ 7, maxY
+ 14);
2128 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2130 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2138 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2140 // if (GetAutoLayout()) Layout();
2143 bool wxWindow::Show( bool show
)
2145 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2148 gtk_widget_show( m_widget
);
2150 gtk_widget_hide( m_widget
);
2157 void wxWindow::Enable( bool enable
)
2159 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2161 m_isEnabled
= enable
;
2163 gtk_widget_set_sensitive( m_widget
, enable
);
2164 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2167 int wxWindow::GetCharHeight() const
2169 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2171 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2173 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2175 return font
->ascent
+ font
->descent
;
2178 int wxWindow::GetCharWidth() const
2180 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2182 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2184 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2186 return gdk_string_width( font
, "H" );
2189 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2190 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2192 wxFont fontToUse
= m_font
;
2193 if (theFont
) fontToUse
= *theFont
;
2195 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2197 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2198 if (x
) (*x
) = gdk_string_width( font
, string
);
2199 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2200 if (descent
) (*descent
) = font
->descent
;
2201 if (externalLeading
) (*externalLeading
) = 0; // ??
2204 void wxWindow::MakeModal( bool modal
)
2208 // Disable all other windows
2209 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2211 wxNode
*node
= wxTopLevelWindows
.First();
2214 wxWindow
*win
= (wxWindow
*)node
->Data();
2215 if (win
!= this) win
->Enable(!modal
);
2217 node
= node
->Next();
2222 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2224 event
.SetEventType( wxEVT_CHAR
);
2226 if (!GetEventHandler()->ProcessEvent( event
))
2232 void wxWindow::SetFocus()
2234 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2236 GtkWidget
*connect_widget
= GetConnectWidget();
2239 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2241 gtk_widget_grab_focus (connect_widget
);
2243 else if (GTK_IS_CONTAINER(connect_widget
))
2245 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2253 wxWindow
*wxWindow::FindFocus()
2255 return g_focusWindow
;
2258 bool wxWindow::AcceptsFocus() const
2260 return IsEnabled() && IsShown() && m_acceptsFocus
;
2263 void wxWindow::AddChild( wxWindow
*child
)
2265 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2266 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2268 m_children
.Append( child
);
2271 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2273 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2275 wxWindow
*oldParent
= GetParent();
2277 if (oldParent
) oldParent
->RemoveChild( this );
2279 gtk_widget_unparent( m_widget
);
2283 newParent
->AddChild( this );
2284 (newParent
->m_insertCallback
)( newParent
, this );
2290 void wxWindow::RemoveChild( wxWindow
*child
)
2292 m_children
.DeleteObject( child
);
2293 child
->m_parent
= (wxWindow
*) NULL
;
2296 void wxWindow::SetReturnCode( int retCode
)
2298 m_retCode
= retCode
;
2301 int wxWindow::GetReturnCode()
2306 void wxWindow::Raise()
2308 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2310 if (m_widget
) gdk_window_raise( m_widget
->window
);
2313 void wxWindow::Lower()
2315 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2317 if (m_widget
) gdk_window_lower( m_widget
->window
);
2320 wxEvtHandler
*wxWindow::GetEventHandler() const
2322 return m_eventHandler
;
2325 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2327 m_eventHandler
= handler
;
2330 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2332 handler
->SetNextHandler(GetEventHandler());
2333 SetEventHandler(handler
);
2336 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2338 if (GetEventHandler())
2340 wxEvtHandler
*handlerA
= GetEventHandler();
2341 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2342 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2343 SetEventHandler(handlerB
);
2347 return (wxEvtHandler
*) NULL
;
2353 return (wxEvtHandler
*) NULL
;
2356 wxValidator
*wxWindow::GetValidator()
2358 return m_windowValidator
;
2361 void wxWindow::SetValidator( const wxValidator
& validator
)
2363 if (m_windowValidator
) delete m_windowValidator
;
2364 m_windowValidator
= validator
.Clone();
2365 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2368 void wxWindow::SetClientObject( wxClientData
*data
)
2370 if (m_clientObject
) delete m_clientObject
;
2371 m_clientObject
= data
;
2374 wxClientData
*wxWindow::GetClientObject()
2376 return m_clientObject
;
2379 void wxWindow::SetClientData( void *data
)
2381 m_clientData
= data
;
2384 void *wxWindow::GetClientData()
2386 return m_clientData
;
2389 bool wxWindow::IsBeingDeleted()
2394 void wxWindow::SetId( wxWindowID id
)
2399 wxWindowID
wxWindow::GetId() const
2404 void wxWindow::SetCursor( const wxCursor
&cursor
)
2406 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2410 if (cursor
== *m_cursor
) return;
2415 *m_cursor
= *wxSTANDARD_CURSOR
;
2418 if ((m_widget
) && (m_widget
->window
))
2419 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2421 if ((m_wxwindow
) && (m_wxwindow
->window
))
2422 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2425 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2430 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2432 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2434 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2438 gdk_window_clear_area( m_wxwindow
->window
,
2440 rect
->width
, rect
->height
);
2444 gdk_window_clear( m_wxwindow
->window
);
2451 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2453 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2457 GdkRectangle gdk_rect
;
2458 gdk_rect
.x
= rect
->x
;
2459 gdk_rect
.y
= rect
->y
;
2460 gdk_rect
.width
= rect
->width
;
2461 gdk_rect
.height
= rect
->height
;
2464 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2466 gtk_widget_draw( m_widget
, &gdk_rect
);
2470 wxRegion
wxWindow::GetUpdateRegion() const
2472 return m_updateRegion
;
2475 bool wxWindow::IsExposed( int x
, int y
) const
2477 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2480 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2482 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2485 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2487 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2490 bool wxWindow::IsExposed( const wxRect
& rect
) const
2492 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2495 void wxWindow::Clear()
2497 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2499 if (m_wxwindow
&& m_wxwindow
->window
)
2501 gdk_window_clear( m_wxwindow
->window
);
2506 void wxWindow::SetToolTip( const wxString
&tip
)
2510 m_toolTip
->SetTip( tip
);
2514 SetToolTip( new wxToolTip( tip
) );
2517 // setting empty tooltip text does not remove the tooltip any more for
2518 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2521 void wxWindow::SetToolTip( wxToolTip
*tip
)
2525 m_toolTip
->SetTip( (char*) NULL
);
2532 m_toolTip
->Apply( this );
2535 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2537 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2539 #endif // wxUSE_TOOLTIPS
2541 wxColour
wxWindow::GetBackgroundColour() const
2543 return m_backgroundColour
;
2546 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2548 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2550 if (m_backgroundColour
== colour
) return;
2552 m_backgroundColour
= colour
;
2553 if (!m_backgroundColour
.Ok()) return;
2555 if (m_wxwindow
&& m_wxwindow
->window
)
2557 /* wxMSW doesn't clear the window here. I don't do that
2558 either to provide compatibility. call Clear() to do
2561 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2562 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2565 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2567 if (sysbg
.Red() == colour
.Red() &&
2568 sysbg
.Green() == colour
.Green() &&
2569 sysbg
.Blue() == colour
.Blue())
2571 m_backgroundColour
= wxNullColour
;
2573 m_backgroundColour
= sysbg
;
2581 wxColour
wxWindow::GetForegroundColour() const
2583 return m_foregroundColour
;
2586 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2588 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2590 if (m_foregroundColour
== colour
) return;
2592 m_foregroundColour
= colour
;
2593 if (!m_foregroundColour
.Ok()) return;
2595 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2596 if (sysbg
.Red() == colour
.Red() &&
2597 sysbg
.Green() == colour
.Green() &&
2598 sysbg
.Blue() == colour
.Blue())
2600 m_backgroundColour
= wxNullColour
;
2602 m_backgroundColour
= sysbg
;
2610 GtkStyle
*wxWindow::GetWidgetStyle()
2612 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2616 gtk_widget_get_style( m_widget
) );
2618 return m_widgetStyle
;
2621 void wxWindow::SetWidgetStyle()
2623 GtkStyle
*style
= GetWidgetStyle();
2625 gdk_font_unref( style
->font
);
2626 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2628 if (m_foregroundColour
.Ok())
2630 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2631 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2632 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2633 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2636 if (m_backgroundColour
.Ok())
2638 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2639 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2640 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2641 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2642 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2643 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2644 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2645 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2646 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2650 void wxWindow::ApplyWidgetStyle()
2654 bool wxWindow::Validate()
2656 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2658 wxNode
*node
= m_children
.First();
2661 wxWindow
*child
= (wxWindow
*)node
->Data();
2662 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2666 node
= node
->Next();
2671 bool wxWindow::TransferDataToWindow()
2673 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2675 wxNode
*node
= m_children
.First();
2678 wxWindow
*child
= (wxWindow
*)node
->Data();
2679 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2680 !child
->GetValidator()->TransferToWindow() )
2682 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2685 node
= node
->Next();
2690 bool wxWindow::TransferDataFromWindow()
2692 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2694 wxNode
*node
= m_children
.First();
2697 wxWindow
*child
= (wxWindow
*)node
->Data();
2698 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2702 node
= node
->Next();
2707 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2709 m_acceleratorTable
= accel
;
2712 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2714 TransferDataToWindow();
2717 void wxWindow::InitDialog()
2719 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2721 wxInitDialogEvent
event(GetId());
2722 event
.SetEventObject( this );
2723 GetEventHandler()->ProcessEvent(event
);
2726 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2728 menu
->SetInvokingWindow( win
);
2729 wxNode
*node
= menu
->m_items
.First();
2732 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2733 if (menuitem
->IsSubMenu())
2735 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2737 node
= node
->Next();
2741 static gint gs_pop_x
= 0;
2742 static gint gs_pop_y
= 0;
2744 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2746 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2751 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2753 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2755 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2757 SetInvokingWindow( menu
, this );
2765 GTK_MENU(menu
->m_menu
),
2766 (GtkWidget
*) NULL
, // parent menu shell
2767 (GtkWidget
*) NULL
, // parent menu item
2768 (GtkMenuPositionFunc
) pop_pos_callback
,
2769 (gpointer
) this, // client data
2770 0, // button used to activate it
2771 0 //gs_timeLastClick // the time of activation
2776 #if wxUSE_DRAG_AND_DROP
2778 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2780 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2782 GtkWidget
*dnd_widget
= GetConnectWidget();
2784 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2786 if (m_dropTarget
) delete m_dropTarget
;
2787 m_dropTarget
= dropTarget
;
2789 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2792 wxDropTarget
*wxWindow::GetDropTarget() const
2794 return m_dropTarget
;
2799 GtkWidget
* wxWindow::GetConnectWidget()
2801 GtkWidget
*connect_widget
= m_widget
;
2802 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2804 return connect_widget
;
2807 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2809 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2810 return (window
== m_widget
->window
);
2813 void wxWindow::SetFont( const wxFont
&font
)
2815 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2817 if (((wxFont
*)&font
)->Ok())
2820 m_font
= *wxSWISS_FONT
;
2822 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2823 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2824 sysbg
.Green() == m_backgroundColour
.Green() &&
2825 sysbg
.Blue() == m_backgroundColour
.Blue())
2827 m_backgroundColour
= wxNullColour
;
2829 m_backgroundColour
= sysbg
;
2837 void wxWindow::SetWindowStyleFlag( long flag
)
2839 m_windowStyle
= flag
;
2842 long wxWindow::GetWindowStyleFlag() const
2844 return m_windowStyle
;
2847 void wxWindow::CaptureMouse()
2849 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2851 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2853 GtkWidget
*connect_widget
= GetConnectWidget();
2854 gtk_grab_add( connect_widget
);
2855 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2857 (GDK_BUTTON_PRESS_MASK
|
2858 GDK_BUTTON_RELEASE_MASK
|
2859 GDK_POINTER_MOTION_MASK
),
2866 void wxWindow::ReleaseMouse()
2868 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2870 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2872 GtkWidget
*connect_widget
= GetConnectWidget();
2873 gtk_grab_remove( connect_widget
);
2874 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2875 g_capturing
= FALSE
;
2878 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2882 wxString
wxWindow::GetTitle() const
2884 return (wxString
&)m_windowName
;
2887 wxString
wxWindow::GetLabel() const
2892 void wxWindow::SetName( const wxString
&name
)
2894 m_windowName
= name
;
2897 wxString
wxWindow::GetName() const
2899 return (wxString
&)m_windowName
;
2902 bool wxWindow::IsShown() const
2907 bool wxWindow::IsRetained()
2912 wxWindow
*wxWindow::FindWindow( long id
)
2914 if (id
== m_windowId
) return this;
2915 wxNode
*node
= m_children
.First();
2918 wxWindow
*child
= (wxWindow
*)node
->Data();
2919 wxWindow
*res
= child
->FindWindow( id
);
2920 if (res
) return res
;
2921 node
= node
->Next();
2923 return (wxWindow
*) NULL
;
2926 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2928 if (name
== m_windowName
) return this;
2929 wxNode
*node
= m_children
.First();
2932 wxWindow
*child
= (wxWindow
*)node
->Data();
2933 wxWindow
*res
= child
->FindWindow( name
);
2934 if (res
) return res
;
2935 node
= node
->Next();
2937 return (wxWindow
*) NULL
;
2940 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2941 int range
, bool refresh
)
2943 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2945 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2947 m_hasScrolling
= TRUE
;
2949 if (orient
== wxHORIZONTAL
)
2951 float fpos
= (float)pos
;
2952 float frange
= (float)range
;
2953 float fthumb
= (float)thumbVisible
;
2954 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2955 if (fpos
< 0.0) fpos
= 0.0;
2957 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2958 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2960 SetScrollPos( orient
, pos
, refresh
);
2964 m_oldHorizontalPos
= fpos
;
2966 m_hAdjust
->lower
= 0.0;
2967 m_hAdjust
->upper
= frange
;
2968 m_hAdjust
->value
= fpos
;
2969 m_hAdjust
->step_increment
= 1.0;
2970 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2971 m_hAdjust
->page_size
= fthumb
;
2975 float fpos
= (float)pos
;
2976 float frange
= (float)range
;
2977 float fthumb
= (float)thumbVisible
;
2978 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2979 if (fpos
< 0.0) fpos
= 0.0;
2981 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2982 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
2984 SetScrollPos( orient
, pos
, refresh
);
2988 m_oldVerticalPos
= fpos
;
2990 m_vAdjust
->lower
= 0.0;
2991 m_vAdjust
->upper
= frange
;
2992 m_vAdjust
->value
= fpos
;
2993 m_vAdjust
->step_increment
= 1.0;
2994 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2995 m_vAdjust
->page_size
= fthumb
;
2998 if (m_wxwindow
->window
)
3000 if (orient
== wxHORIZONTAL
)
3001 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3003 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3005 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3009 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3011 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3013 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3015 if (orient
== wxHORIZONTAL
)
3017 float fpos
= (float)pos
;
3018 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3019 if (fpos
< 0.0) fpos
= 0.0;
3020 m_oldHorizontalPos
= fpos
;
3022 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3023 m_hAdjust
->value
= fpos
;
3027 float fpos
= (float)pos
;
3028 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3029 if (fpos
< 0.0) fpos
= 0.0;
3030 m_oldVerticalPos
= fpos
;
3032 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3033 m_vAdjust
->value
= fpos
;
3038 if (m_wxwindow
->window
)
3040 if (orient
== wxHORIZONTAL
)
3041 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3043 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3048 int wxWindow::GetScrollThumb( int orient
) const
3050 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3052 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3054 if (orient
== wxHORIZONTAL
)
3055 return (int)(m_hAdjust
->page_size
+0.5);
3057 return (int)(m_vAdjust
->page_size
+0.5);
3060 int wxWindow::GetScrollPos( int orient
) const
3062 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3064 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3066 if (orient
== wxHORIZONTAL
)
3067 return (int)(m_hAdjust
->value
+0.5);
3069 return (int)(m_vAdjust
->value
+0.5);
3072 int wxWindow::GetScrollRange( int orient
) const
3074 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3076 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3078 if (orient
== wxHORIZONTAL
)
3079 return (int)(m_hAdjust
->upper
+0.5);
3081 return (int)(m_vAdjust
->upper
+0.5);
3084 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3086 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3088 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3092 GetClientSize( &cw
, &ch
);
3094 int w
= cw
- abs(dx
);
3095 int h
= ch
- abs(dy
);
3096 if ((h
< 0) || (w
< 0))
3103 if (dx
< 0) s_x
= -dx
;
3104 if (dy
< 0) s_y
= -dy
;
3107 if (dx
> 0) d_x
= dx
;
3108 if (dy
> 0) d_y
= dy
;
3112 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3113 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3116 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3117 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3120 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3121 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3122 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3123 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3125 Refresh( TRUE
, &rect
);
3128 //-------------------------------------------------------------------------------------
3130 //-------------------------------------------------------------------------------------
3132 wxLayoutConstraints
*wxWindow::GetConstraints() const
3134 return m_constraints
;
3137 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3141 UnsetConstraints(m_constraints
);
3142 delete m_constraints
;
3144 m_constraints
= constraints
;
3147 // Make sure other windows know they're part of a 'meaningful relationship'
3148 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3149 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3150 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3151 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3152 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3153 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3154 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3155 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3156 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3157 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3158 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3159 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3160 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3161 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3162 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3163 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3169 void wxWindow::SetAutoLayout( bool autoLayout
)
3171 m_autoLayout
= autoLayout
;
3174 bool wxWindow::GetAutoLayout() const
3176 return m_autoLayout
;
3179 wxSizer
*wxWindow::GetSizer() const
3181 return m_windowSizer
;
3184 void wxWindow::SetSizerParent( wxWindow
*win
)
3186 m_sizerParent
= win
;
3189 wxWindow
*wxWindow::GetSizerParent() const
3191 return m_sizerParent
;
3194 // This removes any dangling pointers to this window
3195 // in other windows' constraintsInvolvedIn lists.
3196 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3200 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3201 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3202 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3203 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3204 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3205 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3206 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3207 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3208 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3209 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3210 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3211 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3212 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3213 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3214 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3215 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3219 // Back-pointer to other windows we're involved with, so if we delete
3220 // this window, we must delete any constraints we're involved with.
3221 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3223 if (!m_constraintsInvolvedIn
)
3224 m_constraintsInvolvedIn
= new wxList
;
3225 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3226 m_constraintsInvolvedIn
->Append(otherWin
);
3229 // REMOVE back-pointer to other windows we're involved with.
3230 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3232 if (m_constraintsInvolvedIn
)
3233 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3236 // Reset any constraints that mention this window
3237 void wxWindow::DeleteRelatedConstraints()
3239 if (m_constraintsInvolvedIn
)
3241 wxNode
*node
= m_constraintsInvolvedIn
->First();
3244 wxWindow
*win
= (wxWindow
*)node
->Data();
3245 wxNode
*next
= node
->Next();
3246 wxLayoutConstraints
*constr
= win
->GetConstraints();
3248 // Reset any constraints involving this window
3251 constr
->left
.ResetIfWin((wxWindow
*)this);
3252 constr
->top
.ResetIfWin((wxWindow
*)this);
3253 constr
->right
.ResetIfWin((wxWindow
*)this);
3254 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3255 constr
->width
.ResetIfWin((wxWindow
*)this);
3256 constr
->height
.ResetIfWin((wxWindow
*)this);
3257 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3258 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3263 delete m_constraintsInvolvedIn
;
3264 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3268 void wxWindow::SetSizer(wxSizer
*sizer
)
3270 m_windowSizer
= sizer
;
3272 sizer
->SetSizerParent((wxWindow
*)this);
3279 bool wxWindow::Layout()
3281 if (GetConstraints())
3284 GetClientSize(&w
, &h
);
3285 GetConstraints()->width
.SetValue(w
);
3286 GetConstraints()->height
.SetValue(h
);
3289 // If top level (one sizer), evaluate the sizer's constraints.
3293 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3294 GetSizer()->LayoutPhase1(&noChanges
);
3295 GetSizer()->LayoutPhase2(&noChanges
);
3296 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3301 // Otherwise, evaluate child constraints
3302 ResetConstraints(); // Mark all constraints as unevaluated
3303 DoPhase(1); // Just one phase need if no sizers involved
3305 SetConstraintSizes(); // Recursively set the real window sizes
3311 // Do a phase of evaluating constraints:
3312 // the default behaviour. wxSizers may do a similar
3313 // thing, but also impose their own 'constraints'
3314 // and order the evaluation differently.
3315 bool wxWindow::LayoutPhase1(int *noChanges
)
3317 wxLayoutConstraints
*constr
= GetConstraints();
3320 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3326 bool wxWindow::LayoutPhase2(int *noChanges
)
3336 // Do a phase of evaluating child constraints
3337 bool wxWindow::DoPhase(int phase
)
3339 int noIterations
= 0;
3340 int maxIterations
= 500;
3344 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3348 wxNode
*node
= m_children
.First();
3351 wxWindow
*child
= (wxWindow
*)node
->Data();
3352 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3354 wxLayoutConstraints
*constr
= child
->GetConstraints();
3357 if (succeeded
.Member(child
))
3362 int tempNoChanges
= 0;
3363 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3364 noChanges
+= tempNoChanges
;
3367 succeeded
.Append(child
);
3372 node
= node
->Next();
3379 void wxWindow::ResetConstraints()
3381 wxLayoutConstraints
*constr
= GetConstraints();
3384 constr
->left
.SetDone(FALSE
);
3385 constr
->top
.SetDone(FALSE
);
3386 constr
->right
.SetDone(FALSE
);
3387 constr
->bottom
.SetDone(FALSE
);
3388 constr
->width
.SetDone(FALSE
);
3389 constr
->height
.SetDone(FALSE
);
3390 constr
->centreX
.SetDone(FALSE
);
3391 constr
->centreY
.SetDone(FALSE
);
3393 wxNode
*node
= m_children
.First();
3396 wxWindow
*win
= (wxWindow
*)node
->Data();
3397 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3398 win
->ResetConstraints();
3399 node
= node
->Next();
3403 // Need to distinguish between setting the 'fake' size for
3404 // windows and sizers, and setting the real values.
3405 void wxWindow::SetConstraintSizes(bool recurse
)
3407 wxLayoutConstraints
*constr
= GetConstraints();
3408 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3409 constr
->width
.GetDone() && constr
->height
.GetDone())
3411 int x
= constr
->left
.GetValue();
3412 int y
= constr
->top
.GetValue();
3413 int w
= constr
->width
.GetValue();
3414 int h
= constr
->height
.GetValue();
3416 // If we don't want to resize this window, just move it...
3417 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3418 (constr
->height
.GetRelationship() != wxAsIs
))
3420 // Calls Layout() recursively. AAAGH. How can we stop that.
3421 // Simply take Layout() out of non-top level OnSizes.
3422 SizerSetSize(x
, y
, w
, h
);
3431 char *windowClass
= this->GetClassInfo()->GetClassName();
3434 if (GetName() == "")
3435 winName
= "unnamed";
3437 winName
= GetName();
3438 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3439 (const char *)windowClass
,
3440 (const char *)winName
);
3441 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3442 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3443 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3444 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3445 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3450 wxNode
*node
= m_children
.First();
3453 wxWindow
*win
= (wxWindow
*)node
->Data();
3454 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3455 win
->SetConstraintSizes();
3456 node
= node
->Next();
3461 // This assumes that all sizers are 'on' the same
3462 // window, i.e. the parent of this window.
3463 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3465 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3466 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3470 m_sizerParent
->GetPosition(&xp
, &yp
);
3471 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3476 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3480 TransformSizerToActual(&xx
, &yy
);
3481 SetSize(xx
, yy
, w
, h
);
3484 void wxWindow::SizerMove(int x
, int y
)
3488 TransformSizerToActual(&xx
, &yy
);
3492 // Only set the size/position of the constraint (if any)
3493 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3495 wxLayoutConstraints
*constr
= GetConstraints();
3500 constr
->left
.SetValue(x
);
3501 constr
->left
.SetDone(TRUE
);
3505 constr
->top
.SetValue(y
);
3506 constr
->top
.SetDone(TRUE
);
3510 constr
->width
.SetValue(w
);
3511 constr
->width
.SetDone(TRUE
);
3515 constr
->height
.SetValue(h
);
3516 constr
->height
.SetDone(TRUE
);
3521 void wxWindow::MoveConstraint(int x
, int y
)
3523 wxLayoutConstraints
*constr
= GetConstraints();
3528 constr
->left
.SetValue(x
);
3529 constr
->left
.SetDone(TRUE
);
3533 constr
->top
.SetValue(y
);
3534 constr
->top
.SetDone(TRUE
);
3539 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3541 wxLayoutConstraints
*constr
= GetConstraints();
3544 *w
= constr
->width
.GetValue();
3545 *h
= constr
->height
.GetValue();
3551 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3553 wxLayoutConstraints
*constr
= GetConstraints();
3556 *w
= constr
->width
.GetValue();
3557 *h
= constr
->height
.GetValue();
3560 GetClientSize(w
, h
);
3563 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3565 wxLayoutConstraints
*constr
= GetConstraints();
3568 *x
= constr
->left
.GetValue();
3569 *y
= constr
->top
.GetValue();