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_ISO_Left_Tab
:
249 case GDK_Tab
: key_code
= WXK_TAB
; break;
250 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
251 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
252 case GDK_Return
: key_code
= WXK_RETURN
; break;
253 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
254 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
255 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
256 case GDK_Delete
: key_code
= WXK_DELETE
; break;
257 case GDK_Home
: key_code
= WXK_HOME
; break;
258 case GDK_Left
: key_code
= WXK_LEFT
; break;
259 case GDK_Up
: key_code
= WXK_UP
; break;
260 case GDK_Right
: key_code
= WXK_RIGHT
; break;
261 case GDK_Down
: key_code
= WXK_DOWN
; break;
262 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
263 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
264 case GDK_Next
: key_code
= WXK_NEXT
; break;
265 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
266 case GDK_End
: key_code
= WXK_END
; break;
267 case GDK_Begin
: key_code
= WXK_HOME
; break;
268 case GDK_Select
: key_code
= WXK_SELECT
; break;
269 case GDK_Print
: key_code
= WXK_PRINT
; break;
270 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
271 case GDK_Insert
: key_code
= WXK_INSERT
; break;
272 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
273 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
274 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
275 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
276 case GDK_KP_Up
: key_code
= WXK_UP
; break;
277 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
278 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
279 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
280 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
281 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
282 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
283 case GDK_KP_End
: key_code
= WXK_END
; break;
284 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
285 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
286 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
287 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
288 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
289 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
290 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
291 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
292 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
293 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
294 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
295 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
296 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
297 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
298 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
299 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
300 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
301 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
302 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
303 case GDK_F1
: key_code
= WXK_F1
; break;
304 case GDK_F2
: key_code
= WXK_F2
; break;
305 case GDK_F3
: key_code
= WXK_F3
; break;
306 case GDK_F4
: key_code
= WXK_F4
; break;
307 case GDK_F5
: key_code
= WXK_F5
; break;
308 case GDK_F6
: key_code
= WXK_F6
; break;
309 case GDK_F7
: key_code
= WXK_F7
; break;
310 case GDK_F8
: key_code
= WXK_F8
; break;
311 case GDK_F9
: key_code
= WXK_F9
; break;
312 case GDK_F10
: key_code
= WXK_F10
; break;
313 case GDK_F11
: key_code
= WXK_F11
; break;
314 case GDK_F12
: key_code
= WXK_F12
; break;
317 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
318 key_code
= gdk_event
->keyval
;
322 if (!key_code
) return FALSE
;
324 wxKeyEvent
event( wxEVT_KEY_DOWN
);
325 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
326 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
327 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
328 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
329 event
.m_keyCode
= key_code
;
332 event
.SetEventObject( win
);
334 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
338 wxWindow
*ancestor
= win
;
341 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
344 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
345 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
348 ancestor
= ancestor
->GetParent();
352 // win is a control: tab can be propagated up
354 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
355 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
357 wxNavigationKeyEvent new_event
;
358 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
359 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
360 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
361 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
362 new_event
.SetCurrentFocus( win
);
363 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
367 (gdk_event
->keyval
== GDK_Escape
) )
369 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
370 new_event
.SetEventObject( win
);
371 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
375 Damn, I forgot why this didn't work, but it didn't work.
377 // win is a panel: up can be propagated to the panel
378 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
379 (gdk_event->keyval == GDK_Up))
381 win->m_parent->SetFocus();
385 // win is a panel: left/right can be propagated to the panel
386 if ((!ret) && (win->m_wxwindow) &&
387 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
388 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
390 wxNavigationKeyEvent new_event;
391 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
392 new_event.SetCurrentFocus( win );
393 ret = win->GetEventHandler()->ProcessEvent( new_event );
399 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
405 //-----------------------------------------------------------------------------
406 // "key_release_event" from any window
407 //-----------------------------------------------------------------------------
409 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
411 if (!win
->HasVMT()) return FALSE
;
412 if (g_blockEventsOnDrag
) return FALSE
;
415 printf( "OnKeyRelease from " );
416 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
417 printf( win->GetClassInfo()->GetClassName() );
422 switch (gdk_event
->keyval
)
424 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
425 case GDK_ISO_Left_Tab
:
427 case GDK_Tab
: key_code
= WXK_TAB
; break;
428 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
429 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
430 case GDK_Return
: key_code
= WXK_RETURN
; break;
431 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
432 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
433 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
434 case GDK_Delete
: key_code
= WXK_DELETE
; break;
435 case GDK_Home
: key_code
= WXK_HOME
; break;
436 case GDK_Left
: key_code
= WXK_LEFT
; break;
437 case GDK_Up
: key_code
= WXK_UP
; break;
438 case GDK_Right
: key_code
= WXK_RIGHT
; break;
439 case GDK_Down
: key_code
= WXK_DOWN
; break;
440 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
441 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
442 case GDK_Next
: key_code
= WXK_NEXT
; break;
443 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
444 case GDK_End
: key_code
= WXK_END
; break;
445 case GDK_Begin
: key_code
= WXK_HOME
; break;
446 case GDK_Select
: key_code
= WXK_SELECT
; break;
447 case GDK_Print
: key_code
= WXK_PRINT
; break;
448 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
449 case GDK_Insert
: key_code
= WXK_INSERT
; break;
450 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
451 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
452 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
453 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
454 case GDK_KP_Up
: key_code
= WXK_UP
; break;
455 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
456 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
457 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
458 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
459 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
460 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
461 case GDK_KP_End
: key_code
= WXK_END
; break;
462 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
463 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
464 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
465 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
466 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
467 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
468 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
469 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
470 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
471 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
472 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
473 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
474 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
475 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
476 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
477 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
478 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
479 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
480 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
481 case GDK_F1
: key_code
= WXK_F1
; break;
482 case GDK_F2
: key_code
= WXK_F2
; break;
483 case GDK_F3
: key_code
= WXK_F3
; break;
484 case GDK_F4
: key_code
= WXK_F4
; break;
485 case GDK_F5
: key_code
= WXK_F5
; break;
486 case GDK_F6
: key_code
= WXK_F6
; break;
487 case GDK_F7
: key_code
= WXK_F7
; break;
488 case GDK_F8
: key_code
= WXK_F8
; break;
489 case GDK_F9
: key_code
= WXK_F9
; break;
490 case GDK_F10
: key_code
= WXK_F10
; break;
491 case GDK_F11
: key_code
= WXK_F11
; break;
492 case GDK_F12
: key_code
= WXK_F12
; break;
495 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
496 key_code
= gdk_event
->keyval
;
500 if (!key_code
) return FALSE
;
502 wxKeyEvent
event( wxEVT_KEY_UP
);
503 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
504 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
505 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
506 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
507 event
.m_keyCode
= key_code
;
510 event
.SetEventObject( win
);
512 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
516 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
522 //-----------------------------------------------------------------------------
523 // "button_press_event"
524 //-----------------------------------------------------------------------------
526 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
528 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
530 if (g_blockEventsOnDrag
) return TRUE
;
531 if (g_blockEventsOnScroll
) return TRUE
;
535 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
537 gtk_widget_grab_focus (win
->m_wxwindow
);
540 printf( "GrabFocus from " );
541 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
542 printf( win->GetClassInfo()->GetClassName() );
549 if (!win
->HasVMT()) return TRUE
;
552 printf( "OnButtonPress from " );
553 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
554 printf( win->GetClassInfo()->GetClassName() );
558 wxEventType event_type
= wxEVT_LEFT_DOWN
;
560 if (gdk_event
->button
== 1)
562 switch (gdk_event
->type
)
564 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
565 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
569 else if (gdk_event
->button
== 2)
571 switch (gdk_event
->type
)
573 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
574 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
578 else if (gdk_event
->button
== 3)
580 switch (gdk_event
->type
)
582 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
583 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
588 wxMouseEvent
event( event_type
);
589 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
590 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
591 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
592 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
593 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
594 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
595 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
597 event
.m_x
= (long)gdk_event
->x
;
598 event
.m_y
= (long)gdk_event
->y
;
600 // Some control don't have their own X window and thus cannot get
605 wxNode
*node
= win
->GetChildren().First();
608 wxWindow
*child
= (wxWindow
*)node
->Data();
610 if (child
->m_isStaticBox
)
612 // wxStaticBox is transparent in the box itself
615 int xx1
= child
->m_x
;
616 int yy1
= child
->m_y
;
617 int xx2
= child
->m_x
+ child
->m_width
;
618 int yy2
= child
->m_x
+ child
->m_height
;
621 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
623 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
625 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
627 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
630 event
.m_x
-= child
->m_x
;
631 event
.m_y
-= child
->m_y
;
638 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
639 (child
->m_x
<= event
.m_x
) &&
640 (child
->m_y
<= event
.m_y
) &&
641 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
642 (child
->m_y
+child
->m_height
>= event
.m_y
))
645 event
.m_x
-= child
->m_x
;
646 event
.m_y
-= child
->m_y
;
654 wxPoint
pt(win
->GetClientAreaOrigin());
658 event
.SetEventObject( win
);
660 gs_timeLastClick
= gdk_event
->time
;
662 if (win
->GetEventHandler()->ProcessEvent( event
))
663 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
668 //-----------------------------------------------------------------------------
669 // "button_release_event"
670 //-----------------------------------------------------------------------------
672 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
674 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
676 if (g_blockEventsOnDrag
) return TRUE
;
677 if (g_blockEventsOnScroll
) return TRUE
;
679 if (!win
->HasVMT()) return TRUE
;
682 printf( "OnButtonRelease from " );
683 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
684 printf( win->GetClassInfo()->GetClassName() );
688 wxEventType event_type
= wxEVT_NULL
;
690 switch (gdk_event
->button
)
692 case 1: event_type
= wxEVT_LEFT_UP
; break;
693 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
694 case 3: event_type
= wxEVT_RIGHT_UP
; break;
697 wxMouseEvent
event( event_type
);
698 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
699 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
700 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
701 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
702 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
703 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
704 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
705 event
.m_x
= (long)gdk_event
->x
;
706 event
.m_y
= (long)gdk_event
->y
;
708 // Some control don't have their own X window and thus cannot get
713 wxNode
*node
= win
->GetChildren().First();
716 wxWindow
*child
= (wxWindow
*)node
->Data();
718 if (child
->m_isStaticBox
)
720 // wxStaticBox is transparent in the box itself
723 int xx1
= child
->m_x
;
724 int yy1
= child
->m_y
;
725 int xx2
= child
->m_x
+ child
->m_width
;
726 int yy2
= child
->m_x
+ child
->m_height
;
729 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
731 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
733 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
735 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
738 event
.m_x
-= child
->m_x
;
739 event
.m_y
-= child
->m_y
;
746 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
747 (child
->m_x
<= event
.m_x
) &&
748 (child
->m_y
<= event
.m_y
) &&
749 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
750 (child
->m_y
+child
->m_height
>= event
.m_y
))
753 event
.m_x
-= child
->m_x
;
754 event
.m_y
-= child
->m_y
;
762 wxPoint
pt(win
->GetClientAreaOrigin());
766 event
.SetEventObject( win
);
768 if (win
->GetEventHandler()->ProcessEvent( event
))
769 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
774 //-----------------------------------------------------------------------------
775 // "motion_notify_event"
776 //-----------------------------------------------------------------------------
778 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
780 if (gdk_event
->is_hint
)
784 GdkModifierType state
;
785 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
788 gdk_event
->state
= state
;
791 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return TRUE
;
793 if (g_blockEventsOnDrag
) return TRUE
;
794 if (g_blockEventsOnScroll
) return TRUE
;
796 if (!win
->HasVMT()) return TRUE
;
799 printf( "OnMotion from " );
800 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
801 printf( win->GetClassInfo()->GetClassName() );
805 wxMouseEvent
event( wxEVT_MOTION
);
806 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
807 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
808 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
809 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
810 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
811 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
812 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
814 event
.m_x
= (long)gdk_event
->x
;
815 event
.m_y
= (long)gdk_event
->y
;
817 // Some control don't have their own X window and thus cannot get
822 wxNode
*node
= win
->GetChildren().First();
825 wxWindow
*child
= (wxWindow
*)node
->Data();
827 if (child
->m_isStaticBox
)
829 // wxStaticBox is transparent in the box itself
832 int xx1
= child
->m_x
;
833 int yy1
= child
->m_y
;
834 int xx2
= child
->m_x
+ child
->m_width
;
835 int yy2
= child
->m_x
+ child
->m_height
;
838 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
840 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
842 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
844 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
847 event
.m_x
-= child
->m_x
;
848 event
.m_y
-= child
->m_y
;
855 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
856 (child
->m_x
<= event
.m_x
) &&
857 (child
->m_y
<= event
.m_y
) &&
858 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
859 (child
->m_y
+child
->m_height
>= event
.m_y
))
862 event
.m_x
-= child
->m_x
;
863 event
.m_y
-= child
->m_y
;
871 wxPoint
pt(win
->GetClientAreaOrigin());
875 event
.SetEventObject( win
);
877 if (win
->GetEventHandler()->ProcessEvent( event
))
878 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
883 //-----------------------------------------------------------------------------
885 //-----------------------------------------------------------------------------
887 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
889 if (g_blockEventsOnDrag
) return TRUE
;
895 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
897 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
899 printf( "SetFocus flag from " );
900 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
901 printf( win->GetClassInfo()->GetClassName() );
907 if (!win
->HasVMT()) return TRUE
;
910 printf( "OnSetFocus from " );
911 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
912 printf( win->GetClassInfo()->GetClassName() );
914 printf( WXSTRINGCAST win->GetLabel() );
918 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
919 event
.SetEventObject( win
);
921 if (win
->GetEventHandler()->ProcessEvent( event
))
922 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
927 //-----------------------------------------------------------------------------
929 //-----------------------------------------------------------------------------
931 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
933 if (g_blockEventsOnDrag
) return TRUE
;
936 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
937 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
940 if (!win
->HasVMT()) return TRUE
;
943 printf( "OnKillFocus from " );
944 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
945 printf( win->GetClassInfo()->GetClassName() );
949 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
950 event
.SetEventObject( win
);
952 if (win
->GetEventHandler()->ProcessEvent( event
))
953 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
958 //-----------------------------------------------------------------------------
959 // "enter_notify_event"
960 //-----------------------------------------------------------------------------
962 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
964 if (g_blockEventsOnDrag
) return TRUE
;
966 if ((widget
->window
) && (win
->m_cursor
))
967 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
969 if (widget
->window
!= gdk_event
->window
) return TRUE
;
971 if (!win
->HasVMT()) return TRUE
;
974 printf( "OnEnter from " );
975 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
976 printf( win->GetClassInfo()->GetClassName() );
980 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
981 event
.SetEventObject( win
);
985 GdkModifierType state
= (GdkModifierType
)0;
987 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
989 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
990 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
991 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
992 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
993 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
994 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
995 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1000 wxPoint
pt(win
->GetClientAreaOrigin());
1004 if (win
->GetEventHandler()->ProcessEvent( event
))
1005 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1010 //-----------------------------------------------------------------------------
1011 // "leave_notify_event"
1012 //-----------------------------------------------------------------------------
1014 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1016 if (g_blockEventsOnDrag
) return TRUE
;
1018 if ((widget
->window
) && (win
->m_cursor
))
1019 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1021 if (widget
->window
!= gdk_event
->window
) return TRUE
;
1023 if (!win
->HasVMT()) return TRUE
;
1026 printf( "OnLeave from " );
1027 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1028 printf( win->GetClassInfo()->GetClassName() );
1032 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1033 event
.SetEventObject( win
);
1037 GdkModifierType state
= (GdkModifierType
)0;
1039 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1041 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1042 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1043 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1044 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1045 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1046 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1047 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1049 event
.m_x
= (long)x
;
1050 event
.m_y
= (long)y
;
1052 wxPoint
pt(win
->GetClientAreaOrigin());
1056 if (win
->GetEventHandler()->ProcessEvent( event
))
1057 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1062 //-----------------------------------------------------------------------------
1063 // "value_changed" from m_vAdjust
1064 //-----------------------------------------------------------------------------
1066 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1068 if (g_blockEventsOnDrag
) return;
1071 printf( "OnVScroll from " );
1072 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1073 printf( win->GetClassInfo()->GetClassName() );
1077 if (!win
->HasVMT()) return;
1079 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1080 if (fabs(diff
) < 0.2) return;
1082 wxEventType command
= wxEVT_NULL
;
1084 float line_step
= win
->m_vAdjust
->step_increment
;
1085 float page_step
= win
->m_vAdjust
->page_increment
;
1087 if (win
->m_isScrolling
)
1089 command
= wxEVT_SCROLL_THUMBTRACK
;
1093 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1094 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1095 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1096 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1097 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1098 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1099 else command
= wxEVT_SCROLL_THUMBTRACK
;
1102 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1104 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1105 event
.SetEventObject( win
);
1106 win
->GetEventHandler()->ProcessEvent( event
);
1109 //-----------------------------------------------------------------------------
1110 // "value_changed" from m_hAdjust
1111 //-----------------------------------------------------------------------------
1113 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1115 if (g_blockEventsOnDrag
) return;
1118 printf( "OnHScroll from " );
1119 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1120 printf( win->GetClassInfo()->GetClassName() );
1124 if (!win
->HasVMT()) return;
1126 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1127 if (fabs(diff
) < 0.2) return;
1129 wxEventType command
= wxEVT_NULL
;
1131 float line_step
= win
->m_hAdjust
->step_increment
;
1132 float page_step
= win
->m_hAdjust
->page_increment
;
1134 if (win
->m_isScrolling
)
1136 command
= wxEVT_SCROLL_THUMBTRACK
;
1140 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1141 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1142 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1143 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1144 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1145 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1146 else command
= wxEVT_SCROLL_THUMBTRACK
;
1149 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1151 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1152 event
.SetEventObject( win
);
1153 win
->GetEventHandler()->ProcessEvent( event
);
1156 //-----------------------------------------------------------------------------
1157 // "changed" from m_vAdjust
1158 //-----------------------------------------------------------------------------
1160 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1162 if (g_blockEventsOnDrag
) return;
1165 printf( "OnVScroll change from " );
1166 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1167 printf( win->GetClassInfo()->GetClassName() );
1171 if (!win
->HasVMT()) return;
1173 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1174 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1176 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1177 event
.SetEventObject( win
);
1178 win
->GetEventHandler()->ProcessEvent( event
);
1181 //-----------------------------------------------------------------------------
1182 // "changed" from m_hAdjust
1183 //-----------------------------------------------------------------------------
1185 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1187 if (g_blockEventsOnDrag
) return;
1190 printf( "OnHScroll change from " );
1191 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1192 printf( win->GetClassInfo()->GetClassName() );
1196 if (!win
->HasVMT()) return;
1198 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1199 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1201 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1202 event
.SetEventObject( win
);
1203 win
->GetEventHandler()->ProcessEvent( event
);
1206 //-----------------------------------------------------------------------------
1207 // "button_press_event" from scrollbar
1208 //-----------------------------------------------------------------------------
1210 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1211 GdkEventButton
*WXUNUSED(gdk_event
),
1214 // don't test here as we can release the mouse while being over
1215 // a different window then the slider
1217 // if (gdk_event->window != widget->slider) return FALSE;
1219 win
->m_isScrolling
= TRUE
;
1220 g_blockEventsOnScroll
= TRUE
;
1225 //-----------------------------------------------------------------------------
1226 // "button_release_event" from scrollbar
1227 //-----------------------------------------------------------------------------
1229 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1230 GdkEventButton
*WXUNUSED(gdk_event
),
1234 // don't test here as we can release the mouse while being over
1235 // a different window then the slider
1237 // if (gdk_event->window != widget->slider) return FALSE;
1239 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1241 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1242 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1244 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1246 win
->m_isScrolling
= FALSE
;
1247 g_blockEventsOnScroll
= FALSE
;
1252 //-----------------------------------------------------------------------------
1253 // InsertChild for wxWindow.
1254 //-----------------------------------------------------------------------------
1256 /* Callback for wxWindow. This very strange beast has to be used because
1257 * C++ has no virtual methods in a constructor. We have to emulate a
1258 * virtual function here as wxNotebook requires a different way to insert
1259 * a child in it. I had opted for creating a wxNotebookPage window class
1260 * which would have made this superfluous (such in the MDI window system),
1261 * but no-one was listening to me... */
1263 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1265 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1266 GTK_WIDGET(child
->m_widget
),
1270 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1274 if (wxIS_KIND_OF(parent
,wxFrame
))
1276 parent
->m_sizeSet
= FALSE
;
1279 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1281 /* we now allow a window to get the focus as long as it
1282 doesn't have any children. */
1283 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1287 //-----------------------------------------------------------------------------
1289 //-----------------------------------------------------------------------------
1291 wxWindow
* wxGetActiveWindow()
1293 return g_focusWindow
;
1296 //-----------------------------------------------------------------------------
1298 //-----------------------------------------------------------------------------
1300 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1302 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1303 EVT_SIZE(wxWindow::OnSize
)
1304 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1305 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1306 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1309 wxWindow::wxWindow()
1311 m_widget
= (GtkWidget
*) NULL
;
1312 m_wxwindow
= (GtkWidget
*) NULL
;
1313 m_parent
= (wxWindow
*) NULL
;
1314 m_children
.DeleteContents( FALSE
);
1327 m_eventHandler
= this;
1328 m_windowValidator
= (wxValidator
*) NULL
;
1332 m_cursor
= (wxCursor
*) NULL
;
1333 m_font
= *wxSWISS_FONT
;
1335 m_windowName
= "noname";
1337 m_constraints
= (wxLayoutConstraints
*) NULL
;
1338 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1339 m_windowSizer
= (wxSizer
*) NULL
;
1340 m_sizerParent
= (wxWindow
*) NULL
;
1341 m_autoLayout
= FALSE
;
1345 m_needParent
= TRUE
;
1347 m_hasScrolling
= FALSE
;
1348 m_isScrolling
= FALSE
;
1349 m_hAdjust
= (GtkAdjustment
*) NULL
;
1350 m_vAdjust
= (GtkAdjustment
*) NULL
;
1351 m_oldHorizontalPos
= 0.0;
1352 m_oldVerticalPos
= 0.0;
1357 #if wxUSE_DRAG_AND_DROP
1358 m_dropTarget
= (wxDropTarget
*) NULL
;
1361 m_scrollGC
= (GdkGC
*) NULL
;
1362 m_widgetStyle
= (GtkStyle
*) NULL
;
1364 m_insertCallback
= wxInsertChildInWindow
;
1366 m_clientObject
= (wxClientData
*) NULL
;
1367 m_clientData
= NULL
;
1369 m_isStaticBox
= FALSE
;
1370 m_acceptsFocus
= FALSE
;
1373 m_toolTip
= (wxToolTip
*) NULL
;
1374 #endif // wxUSE_TOOLTIPS
1377 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1378 const wxPoint
&pos
, const wxSize
&size
,
1379 long style
, const wxString
&name
)
1381 m_insertCallback
= wxInsertChildInWindow
;
1382 Create( parent
, id
, pos
, size
, style
, name
);
1385 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1386 const wxPoint
&pos
, const wxSize
&size
,
1387 long style
, const wxString
&name
)
1391 m_needParent
= TRUE
;
1393 PreCreation( parent
, id
, pos
, size
, style
, name
);
1395 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1396 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1399 debug_focus_in( m_widget
, "wxWindow::m_widget", name
);
1402 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1405 debug_focus_in( s_window
->hscrollbar
, "wxWindow::hsrcollbar", name
);
1406 debug_focus_in( s_window
->vscrollbar
, "wxWindow::vsrcollbar", name
);
1409 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1410 scroll_class
->scrollbar_spacing
= 0;
1412 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1414 m_oldHorizontalPos
= 0.0;
1415 m_oldVerticalPos
= 0.0;
1417 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1418 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1420 m_wxwindow
= gtk_myfixed_new();
1423 debug_focus_in( m_wxwindow
, "wxWindow::m_wxwindow", name
);
1426 #ifdef NEW_GTK_SCROLL_CODE
1427 gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(m_widget
), m_wxwindow
);
1428 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->child
);
1430 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1431 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1435 debug_focus_in( GTK_WIDGET(viewport
), "wxWindow::viewport", name
);
1438 if (m_windowStyle
& wxRAISED_BORDER
)
1440 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1442 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1444 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1448 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1451 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1453 /* we now allow a window to get the focus as long as it
1454 doesn't have any children. */
1455 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1456 m_acceptsFocus
= FALSE
;
1460 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1461 m_acceptsFocus
= TRUE
;
1464 // shut the viewport up
1465 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1466 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1468 // I _really_ don't want scrollbars in the beginning
1469 m_vAdjust
->lower
= 0.0;
1470 m_vAdjust
->upper
= 1.0;
1471 m_vAdjust
->value
= 0.0;
1472 m_vAdjust
->step_increment
= 1.0;
1473 m_vAdjust
->page_increment
= 1.0;
1474 m_vAdjust
->page_size
= 5.0;
1475 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1476 m_hAdjust
->lower
= 0.0;
1477 m_hAdjust
->upper
= 1.0;
1478 m_hAdjust
->value
= 0.0;
1479 m_hAdjust
->step_increment
= 1.0;
1480 m_hAdjust
->page_increment
= 1.0;
1481 m_hAdjust
->page_size
= 5.0;
1482 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1484 // these handlers block mouse events to any window during scrolling
1485 // such as motion events and prevent GTK and wxWindows from fighting
1486 // over where the slider should be
1488 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1489 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1491 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1492 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1494 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1495 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1497 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1498 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1500 // these handers het notified when screen updates are required either when
1501 // scrolling or when the window size (and therefore scrollbar configuration)
1504 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1505 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1506 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1507 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1509 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1510 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1511 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1512 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1514 gtk_widget_show( m_wxwindow
);
1516 if (m_parent
) m_parent
->AddChild( this );
1518 (m_parent
->m_insertCallback
)( m_parent
, this );
1527 wxWindow::~wxWindow()
1529 // Remove potential dangling pointer
1530 if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel
)))
1532 wxPanel
* panel
= (wxPanel
*) GetParent();
1533 if (panel
->GetLastFocus() == this)
1534 panel
->SetLastFocus((wxWindow
*) NULL
);
1539 #if wxUSE_DRAG_AND_DROP
1540 wxDELETE(m_dropTarget
);
1544 wxDELETE(m_toolTip
);
1545 #endif // wxUSE_TOOLTIPS
1547 if (m_parent
) m_parent
->RemoveChild( this );
1548 if (m_widget
) Show( FALSE
);
1552 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1554 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1556 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1558 if (m_widget
) gtk_widget_destroy( m_widget
);
1560 if (m_cursor
) delete m_cursor
;
1562 DeleteRelatedConstraints();
1565 // This removes any dangling pointers to this window
1566 // in other windows' constraintsInvolvedIn lists.
1567 UnsetConstraints(m_constraints
);
1568 delete m_constraints
;
1569 m_constraints
= (wxLayoutConstraints
*) NULL
;
1573 delete m_windowSizer
;
1574 m_windowSizer
= (wxSizer
*) NULL
;
1576 // If this is a child of a sizer, remove self from parent
1577 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1579 // Just in case the window has been Closed, but
1580 // we're then deleting immediately: don't leave
1581 // dangling pointers.
1582 wxPendingDelete
.DeleteObject(this);
1584 // Just in case we've loaded a top-level window via
1585 // wxWindow::LoadNativeDialog but we weren't a dialog
1587 wxTopLevelWindows
.DeleteObject(this);
1589 if (m_windowValidator
) delete m_windowValidator
;
1591 if (m_clientObject
) delete m_clientObject
;
1594 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1595 const wxPoint
&pos
, const wxSize
&size
,
1596 long style
, const wxString
&name
)
1598 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1600 m_widget
= (GtkWidget
*) NULL
;
1601 m_wxwindow
= (GtkWidget
*) NULL
;
1604 m_children
.DeleteContents( FALSE
);
1607 if (m_width
== -1) m_width
= 20;
1609 if (m_height
== -1) m_height
= 20;
1614 if (!m_needParent
) // some reasonable defaults
1618 m_x
= (gdk_screen_width () - m_width
) / 2;
1619 if (m_x
< 10) m_x
= 10;
1623 m_y
= (gdk_screen_height () - m_height
) / 2;
1624 if (m_y
< 10) m_y
= 10;
1635 m_eventHandler
= this;
1637 m_windowId
= id
== -1 ? wxNewId() : id
;
1641 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1642 m_font
= *wxSWISS_FONT
;
1643 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1644 m_foregroundColour
= *wxBLACK
;
1645 m_windowStyle
= style
;
1646 m_windowName
= name
;
1648 m_constraints
= (wxLayoutConstraints
*) NULL
;
1649 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1650 m_windowSizer
= (wxSizer
*) NULL
;
1651 m_sizerParent
= (wxWindow
*) NULL
;
1652 m_autoLayout
= FALSE
;
1654 m_hasScrolling
= FALSE
;
1655 m_isScrolling
= FALSE
;
1656 m_hAdjust
= (GtkAdjustment
*) NULL
;
1657 m_vAdjust
= (GtkAdjustment
*) NULL
;
1658 m_oldHorizontalPos
= 0.0;
1659 m_oldVerticalPos
= 0.0;
1664 #if wxUSE_DRAG_AND_DROP
1665 m_dropTarget
= (wxDropTarget
*) NULL
;
1668 m_windowValidator
= (wxValidator
*) NULL
;
1669 m_scrollGC
= (GdkGC
*) NULL
;
1670 m_widgetStyle
= (GtkStyle
*) NULL
;
1672 m_clientObject
= (wxClientData
*)NULL
;
1673 m_clientData
= NULL
;
1675 m_isStaticBox
= FALSE
;
1678 m_toolTip
= (wxToolTip
*) NULL
;
1679 #endif // wxUSE_TOOLTIPS
1682 void wxWindow::PostCreation()
1686 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1687 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1689 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1690 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1693 ConnectWidget( GetConnectWidget() );
1695 if (m_widget
&& m_parent
) gtk_widget_realize( m_widget
);
1697 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1699 SetCursor( *wxSTANDARD_CURSOR
);
1704 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1706 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1707 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1709 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1710 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1712 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1713 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1715 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1716 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1718 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1719 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1721 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1722 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1724 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1725 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1727 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1728 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1730 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1731 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1734 bool wxWindow::HasVMT()
1739 bool wxWindow::Close( bool force
)
1741 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1743 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1744 event
.SetEventObject(this);
1745 event
.SetCanVeto(!force
);
1747 // return FALSE if window wasn't closed because the application vetoed the
1749 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1752 bool wxWindow::Destroy()
1754 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1761 bool wxWindow::DestroyChildren()
1764 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1767 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1770 if (m_children
.Member(child
)) delete node
;
1776 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1778 // are we to set fonts here ?
1781 wxPoint
wxWindow::GetClientAreaOrigin() const
1783 return wxPoint(0,0);
1786 void wxWindow::AdjustForParentClientOrigin( int& x
, int& y
, int sizeFlags
)
1788 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1790 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1796 void wxWindow::SetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1798 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1799 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1801 if (m_resizing
) return; // I don't like recursions
1804 if (m_parent
->m_wxwindow
== NULL
) // i.e. wxNotebook
1806 // don't set the size for children of wxNotebook, just take the values.
1814 int old_width
= m_width
;
1815 int old_height
= m_height
;
1817 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1819 if (x
!= -1) m_x
= x
;
1820 if (y
!= -1) m_y
= y
;
1821 if (width
!= -1) m_width
= width
;
1822 if (height
!= -1) m_height
= height
;
1832 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1834 if (width
== -1) m_width
= 80;
1837 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1839 if (height
== -1) m_height
= 26;
1842 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1843 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1844 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1845 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1847 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1849 /* the default button has a border around it */
1852 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1853 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
-border
, m_y
+pt
.y
-border
);
1855 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1859 wxPoint
pt( m_parent
->GetClientAreaOrigin() );
1860 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
+pt
.x
, m_y
+pt
.y
);
1862 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1863 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1869 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1870 event
.SetEventObject( this );
1871 GetEventHandler()->ProcessEvent( event
);
1876 void wxWindow::OnInternalIdle()
1881 void wxWindow::SetSize( int width
, int height
)
1883 SetSize( -1, -1, width
, height
, wxSIZE_USE_EXISTING
);
1886 void wxWindow::Move( int x
, int y
)
1888 SetSize( x
, y
, -1, -1, wxSIZE_USE_EXISTING
);
1891 void wxWindow::GetSize( int *width
, int *height
) const
1893 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1895 if (width
) (*width
) = m_width
;
1896 if (height
) (*height
) = m_height
;
1899 void wxWindow::SetClientSize( int width
, int height
)
1901 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1905 SetSize( width
, height
);
1912 if (!m_hasScrolling
)
1914 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1916 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1917 (m_windowStyle
& wxSUNKEN_BORDER
))
1919 dw
+= 2 * window_class
->xthickness
;
1920 dh
+= 2 * window_class
->ythickness
;
1925 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1926 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1928 #ifdef NEW_GTK_SCROLL_CODE
1929 GtkWidget
*viewport
= scroll_window
->child
;
1931 GtkWidget
*viewport
= scroll_window
->viewport
;
1934 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1936 GtkWidget
*hscrollbar
= scroll_window
->hscrollbar
;
1937 GtkWidget
*vscrollbar
= scroll_window
->vscrollbar
;
1939 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1940 (m_windowStyle
& wxSUNKEN_BORDER
))
1942 dw
+= 2 * viewport_class
->xthickness
;
1943 dh
+= 2 * viewport_class
->ythickness
;
1946 if (scroll_window
->vscrollbar_visible
)
1948 dw
+= vscrollbar
->allocation
.width
;
1949 dw
+= scroll_class
->scrollbar_spacing
;
1952 if (scroll_window
->hscrollbar_visible
)
1954 dh
+= hscrollbar
->allocation
.height
;
1955 dw
+= scroll_class
->scrollbar_spacing
;
1959 SetSize( width
+dw
, height
+dh
);
1963 void wxWindow::GetClientSize( int *width
, int *height
) const
1965 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1969 if (width
) (*width
) = m_width
;
1970 if (height
) (*height
) = m_height
;
1977 if (!m_hasScrolling
)
1979 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1981 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1982 (m_windowStyle
& wxSUNKEN_BORDER
))
1984 dw
+= 2 * window_class
->xthickness
;
1985 dh
+= 2 * window_class
->ythickness
;
1990 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1991 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1993 #ifdef NEW_GTK_SCROLL_CODE
1994 GtkWidget
*viewport
= scroll_window
->child
;
1996 GtkWidget
*viewport
= scroll_window
->viewport
;
1999 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2001 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2002 (m_windowStyle
& wxSUNKEN_BORDER
))
2004 dw
+= 2 * viewport_class
->xthickness
;
2005 dh
+= 2 * viewport_class
->ythickness
;
2008 if (scroll_window
->vscrollbar_visible
)
2010 // dw += vscrollbar->allocation.width;
2011 dw
+= 15; // range.slider_width = 11 + 2*2pts edge
2012 dw
+= scroll_class
->scrollbar_spacing
;
2015 if (scroll_window
->hscrollbar_visible
)
2017 // dh += hscrollbar->allocation.height;
2019 dh
+= scroll_class
->scrollbar_spacing
;
2023 if (width
) (*width
) = m_width
- dw
;
2024 if (height
) (*height
) = m_height
- dh
;
2028 void wxWindow::GetPosition( int *x
, int *y
) const
2030 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2036 void wxWindow::ClientToScreen( int *x
, int *y
)
2038 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2040 GdkWindow
*source
= (GdkWindow
*) NULL
;
2042 source
= m_wxwindow
->window
;
2044 source
= m_widget
->window
;
2048 gdk_window_get_origin( source
, &org_x
, &org_y
);
2052 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2054 org_x
+= m_widget
->allocation
.x
;
2055 org_y
+= m_widget
->allocation
.y
;
2059 wxPoint
pt(GetClientAreaOrigin());
2067 void wxWindow::ScreenToClient( int *x
, int *y
)
2069 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2071 GdkWindow
*source
= (GdkWindow
*) NULL
;
2073 source
= m_wxwindow
->window
;
2075 source
= m_widget
->window
;
2079 gdk_window_get_origin( source
, &org_x
, &org_y
);
2083 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2085 org_x
+= m_widget
->allocation
.x
;
2086 org_y
+= m_widget
->allocation
.y
;
2090 wxPoint
pt(GetClientAreaOrigin());
2098 void wxWindow::Centre( int direction
)
2100 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2109 m_parent
->GetSize( &p_w
, &p_h
);
2110 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2111 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2115 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2116 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2122 void wxWindow::Fit()
2124 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2128 wxNode
*node
= m_children
.First();
2131 wxWindow
*win
= (wxWindow
*)node
->Data();
2133 win
->GetPosition(&wx
, &wy
);
2134 win
->GetSize(&ww
, &wh
);
2135 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2136 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2138 node
= node
->Next();
2141 SetClientSize(maxX
+ 7, maxY
+ 14);
2144 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2146 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2154 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2156 // if (GetAutoLayout()) Layout();
2159 bool wxWindow::Show( bool show
)
2161 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2164 gtk_widget_show( m_widget
);
2166 gtk_widget_hide( m_widget
);
2173 void wxWindow::Enable( bool enable
)
2175 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2177 m_isEnabled
= enable
;
2179 gtk_widget_set_sensitive( m_widget
, enable
);
2180 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2183 int wxWindow::GetCharHeight() const
2185 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2187 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2189 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2191 return font
->ascent
+ font
->descent
;
2194 int wxWindow::GetCharWidth() const
2196 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2198 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2200 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2202 return gdk_string_width( font
, "H" );
2205 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2206 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2208 wxFont fontToUse
= m_font
;
2209 if (theFont
) fontToUse
= *theFont
;
2211 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2213 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2214 if (x
) (*x
) = gdk_string_width( font
, string
);
2215 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2216 if (descent
) (*descent
) = font
->descent
;
2217 if (externalLeading
) (*externalLeading
) = 0; // ??
2220 void wxWindow::MakeModal( bool modal
)
2224 // Disable all other windows
2225 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2227 wxNode
*node
= wxTopLevelWindows
.First();
2230 wxWindow
*win
= (wxWindow
*)node
->Data();
2231 if (win
!= this) win
->Enable(!modal
);
2233 node
= node
->Next();
2238 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2240 event
.SetEventType( wxEVT_CHAR
);
2242 if (!GetEventHandler()->ProcessEvent( event
))
2248 void wxWindow::SetFocus()
2250 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2252 GtkWidget
*connect_widget
= GetConnectWidget();
2255 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2257 gtk_widget_grab_focus (connect_widget
);
2259 else if (GTK_IS_CONTAINER(connect_widget
))
2261 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2269 wxWindow
*wxWindow::FindFocus()
2271 return g_focusWindow
;
2274 bool wxWindow::AcceptsFocus() const
2276 return IsEnabled() && IsShown() && m_acceptsFocus
;
2279 void wxWindow::AddChild( wxWindow
*child
)
2281 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2282 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2284 m_children
.Append( child
);
2287 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2289 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2291 wxWindow
*oldParent
= GetParent();
2293 if (oldParent
) oldParent
->RemoveChild( this );
2295 gtk_widget_unparent( m_widget
);
2299 newParent
->AddChild( this );
2300 (newParent
->m_insertCallback
)( newParent
, this );
2306 void wxWindow::RemoveChild( wxWindow
*child
)
2308 m_children
.DeleteObject( child
);
2309 child
->m_parent
= (wxWindow
*) NULL
;
2312 void wxWindow::SetReturnCode( int retCode
)
2314 m_retCode
= retCode
;
2317 int wxWindow::GetReturnCode()
2322 void wxWindow::Raise()
2324 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2326 if (m_widget
) gdk_window_raise( m_widget
->window
);
2329 void wxWindow::Lower()
2331 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2333 if (m_widget
) gdk_window_lower( m_widget
->window
);
2336 wxEvtHandler
*wxWindow::GetEventHandler() const
2338 return m_eventHandler
;
2341 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2343 m_eventHandler
= handler
;
2346 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2348 handler
->SetNextHandler(GetEventHandler());
2349 SetEventHandler(handler
);
2352 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2354 if (GetEventHandler())
2356 wxEvtHandler
*handlerA
= GetEventHandler();
2357 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2358 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2359 SetEventHandler(handlerB
);
2363 return (wxEvtHandler
*) NULL
;
2369 return (wxEvtHandler
*) NULL
;
2372 wxValidator
*wxWindow::GetValidator()
2374 return m_windowValidator
;
2377 void wxWindow::SetValidator( const wxValidator
& validator
)
2379 if (m_windowValidator
) delete m_windowValidator
;
2380 m_windowValidator
= validator
.Clone();
2381 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2384 void wxWindow::SetClientObject( wxClientData
*data
)
2386 if (m_clientObject
) delete m_clientObject
;
2387 m_clientObject
= data
;
2390 wxClientData
*wxWindow::GetClientObject()
2392 return m_clientObject
;
2395 void wxWindow::SetClientData( void *data
)
2397 m_clientData
= data
;
2400 void *wxWindow::GetClientData()
2402 return m_clientData
;
2405 bool wxWindow::IsBeingDeleted()
2410 void wxWindow::SetId( wxWindowID id
)
2415 wxWindowID
wxWindow::GetId() const
2420 void wxWindow::SetCursor( const wxCursor
&cursor
)
2422 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2426 if (cursor
== *m_cursor
) return;
2431 *m_cursor
= *wxSTANDARD_CURSOR
;
2434 if ((m_widget
) && (m_widget
->window
))
2435 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2437 if ((m_wxwindow
) && (m_wxwindow
->window
))
2438 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2441 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2446 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2448 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2450 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2454 gdk_window_clear_area( m_wxwindow
->window
,
2456 rect
->width
, rect
->height
);
2460 gdk_window_clear( m_wxwindow
->window
);
2467 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2469 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2473 GdkRectangle gdk_rect
;
2474 gdk_rect
.x
= rect
->x
;
2475 gdk_rect
.y
= rect
->y
;
2476 gdk_rect
.width
= rect
->width
;
2477 gdk_rect
.height
= rect
->height
;
2480 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2482 gtk_widget_draw( m_widget
, &gdk_rect
);
2486 wxRegion
wxWindow::GetUpdateRegion() const
2488 return m_updateRegion
;
2491 bool wxWindow::IsExposed( int x
, int y
) const
2493 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2496 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2498 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2501 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2503 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2506 bool wxWindow::IsExposed( const wxRect
& rect
) const
2508 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2511 void wxWindow::Clear()
2513 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2515 if (m_wxwindow
&& m_wxwindow
->window
)
2517 gdk_window_clear( m_wxwindow
->window
);
2522 void wxWindow::SetToolTip( const wxString
&tip
)
2526 m_toolTip
->SetTip( tip
);
2530 SetToolTip( new wxToolTip( tip
) );
2533 // setting empty tooltip text does not remove the tooltip any more for
2534 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2537 void wxWindow::SetToolTip( wxToolTip
*tip
)
2541 m_toolTip
->SetTip( (char*) NULL
);
2548 m_toolTip
->Apply( this );
2551 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2553 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2555 #endif // wxUSE_TOOLTIPS
2557 wxColour
wxWindow::GetBackgroundColour() const
2559 return m_backgroundColour
;
2562 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2564 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2566 if (m_backgroundColour
== colour
) return;
2568 m_backgroundColour
= colour
;
2569 if (!m_backgroundColour
.Ok()) return;
2571 if (m_wxwindow
&& m_wxwindow
->window
)
2573 /* wxMSW doesn't clear the window here. I don't do that
2574 either to provide compatibility. call Clear() to do
2577 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2578 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2581 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2583 if (sysbg
.Red() == colour
.Red() &&
2584 sysbg
.Green() == colour
.Green() &&
2585 sysbg
.Blue() == colour
.Blue())
2587 m_backgroundColour
= wxNullColour
;
2589 m_backgroundColour
= sysbg
;
2597 wxColour
wxWindow::GetForegroundColour() const
2599 return m_foregroundColour
;
2602 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2604 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2606 if (m_foregroundColour
== colour
) return;
2608 m_foregroundColour
= colour
;
2609 if (!m_foregroundColour
.Ok()) return;
2611 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2612 if (sysbg
.Red() == colour
.Red() &&
2613 sysbg
.Green() == colour
.Green() &&
2614 sysbg
.Blue() == colour
.Blue())
2616 m_backgroundColour
= wxNullColour
;
2618 m_backgroundColour
= sysbg
;
2626 GtkStyle
*wxWindow::GetWidgetStyle()
2628 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2632 gtk_widget_get_style( m_widget
) );
2634 return m_widgetStyle
;
2637 void wxWindow::SetWidgetStyle()
2639 GtkStyle
*style
= GetWidgetStyle();
2641 gdk_font_unref( style
->font
);
2642 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2644 if (m_foregroundColour
.Ok())
2646 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2647 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2648 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2649 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2652 if (m_backgroundColour
.Ok())
2654 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2655 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2656 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2657 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2658 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2659 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2660 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2661 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2662 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2666 void wxWindow::ApplyWidgetStyle()
2670 bool wxWindow::Validate()
2672 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2674 wxNode
*node
= m_children
.First();
2677 wxWindow
*child
= (wxWindow
*)node
->Data();
2678 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2682 node
= node
->Next();
2687 bool wxWindow::TransferDataToWindow()
2689 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2691 wxNode
*node
= m_children
.First();
2694 wxWindow
*child
= (wxWindow
*)node
->Data();
2695 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2696 !child
->GetValidator()->TransferToWindow() )
2698 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2701 node
= node
->Next();
2706 bool wxWindow::TransferDataFromWindow()
2708 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2710 wxNode
*node
= m_children
.First();
2713 wxWindow
*child
= (wxWindow
*)node
->Data();
2714 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2718 node
= node
->Next();
2723 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2725 m_acceleratorTable
= accel
;
2728 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2730 TransferDataToWindow();
2733 void wxWindow::InitDialog()
2735 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2737 wxInitDialogEvent
event(GetId());
2738 event
.SetEventObject( this );
2739 GetEventHandler()->ProcessEvent(event
);
2742 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2744 menu
->SetInvokingWindow( win
);
2745 wxNode
*node
= menu
->m_items
.First();
2748 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2749 if (menuitem
->IsSubMenu())
2751 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2753 node
= node
->Next();
2757 static gint gs_pop_x
= 0;
2758 static gint gs_pop_y
= 0;
2760 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2762 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2767 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2769 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2771 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2773 SetInvokingWindow( menu
, this );
2781 GTK_MENU(menu
->m_menu
),
2782 (GtkWidget
*) NULL
, // parent menu shell
2783 (GtkWidget
*) NULL
, // parent menu item
2784 (GtkMenuPositionFunc
) pop_pos_callback
,
2785 (gpointer
) this, // client data
2786 0, // button used to activate it
2787 0 //gs_timeLastClick // the time of activation
2792 #if wxUSE_DRAG_AND_DROP
2794 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2796 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2798 GtkWidget
*dnd_widget
= GetConnectWidget();
2800 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2802 if (m_dropTarget
) delete m_dropTarget
;
2803 m_dropTarget
= dropTarget
;
2805 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2808 wxDropTarget
*wxWindow::GetDropTarget() const
2810 return m_dropTarget
;
2815 GtkWidget
* wxWindow::GetConnectWidget()
2817 GtkWidget
*connect_widget
= m_widget
;
2818 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2820 return connect_widget
;
2823 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2825 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2826 return (window
== m_widget
->window
);
2829 void wxWindow::SetFont( const wxFont
&font
)
2831 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2833 if (((wxFont
*)&font
)->Ok())
2836 m_font
= *wxSWISS_FONT
;
2838 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2839 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2840 sysbg
.Green() == m_backgroundColour
.Green() &&
2841 sysbg
.Blue() == m_backgroundColour
.Blue())
2843 m_backgroundColour
= wxNullColour
;
2845 m_backgroundColour
= sysbg
;
2853 void wxWindow::SetWindowStyleFlag( long flag
)
2855 m_windowStyle
= flag
;
2858 long wxWindow::GetWindowStyleFlag() const
2860 return m_windowStyle
;
2863 void wxWindow::CaptureMouse()
2865 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2867 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2869 GtkWidget
*connect_widget
= GetConnectWidget();
2870 gtk_grab_add( connect_widget
);
2871 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2873 (GDK_BUTTON_PRESS_MASK
|
2874 GDK_BUTTON_RELEASE_MASK
|
2875 GDK_POINTER_MOTION_MASK
),
2882 void wxWindow::ReleaseMouse()
2884 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2886 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2888 GtkWidget
*connect_widget
= GetConnectWidget();
2889 gtk_grab_remove( connect_widget
);
2890 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2891 g_capturing
= FALSE
;
2894 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2898 wxString
wxWindow::GetTitle() const
2900 return (wxString
&)m_windowName
;
2903 wxString
wxWindow::GetLabel() const
2908 void wxWindow::SetName( const wxString
&name
)
2910 m_windowName
= name
;
2913 wxString
wxWindow::GetName() const
2915 return (wxString
&)m_windowName
;
2918 bool wxWindow::IsShown() const
2923 bool wxWindow::IsRetained()
2928 wxWindow
*wxWindow::FindWindow( long id
)
2930 if (id
== m_windowId
) return this;
2931 wxNode
*node
= m_children
.First();
2934 wxWindow
*child
= (wxWindow
*)node
->Data();
2935 wxWindow
*res
= child
->FindWindow( id
);
2936 if (res
) return res
;
2937 node
= node
->Next();
2939 return (wxWindow
*) NULL
;
2942 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2944 if (name
== m_windowName
) return this;
2945 wxNode
*node
= m_children
.First();
2948 wxWindow
*child
= (wxWindow
*)node
->Data();
2949 wxWindow
*res
= child
->FindWindow( name
);
2950 if (res
) return res
;
2951 node
= node
->Next();
2953 return (wxWindow
*) NULL
;
2956 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2957 int range
, bool refresh
)
2959 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2961 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2963 m_hasScrolling
= TRUE
;
2965 if (orient
== wxHORIZONTAL
)
2967 float fpos
= (float)pos
;
2968 float frange
= (float)range
;
2969 float fthumb
= (float)thumbVisible
;
2970 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2971 if (fpos
< 0.0) fpos
= 0.0;
2973 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
2974 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
2976 SetScrollPos( orient
, pos
, refresh
);
2980 m_oldHorizontalPos
= fpos
;
2982 m_hAdjust
->lower
= 0.0;
2983 m_hAdjust
->upper
= frange
;
2984 m_hAdjust
->value
= fpos
;
2985 m_hAdjust
->step_increment
= 1.0;
2986 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
2987 m_hAdjust
->page_size
= fthumb
;
2991 float fpos
= (float)pos
;
2992 float frange
= (float)range
;
2993 float fthumb
= (float)thumbVisible
;
2994 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
2995 if (fpos
< 0.0) fpos
= 0.0;
2997 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
2998 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3000 SetScrollPos( orient
, pos
, refresh
);
3004 m_oldVerticalPos
= fpos
;
3006 m_vAdjust
->lower
= 0.0;
3007 m_vAdjust
->upper
= frange
;
3008 m_vAdjust
->value
= fpos
;
3009 m_vAdjust
->step_increment
= 1.0;
3010 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3011 m_vAdjust
->page_size
= fthumb
;
3014 if (m_wxwindow
->window
)
3016 if (orient
== wxHORIZONTAL
)
3017 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3019 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3021 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3025 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3027 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3029 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3031 if (orient
== wxHORIZONTAL
)
3033 float fpos
= (float)pos
;
3034 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3035 if (fpos
< 0.0) fpos
= 0.0;
3036 m_oldHorizontalPos
= fpos
;
3038 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3039 m_hAdjust
->value
= fpos
;
3043 float fpos
= (float)pos
;
3044 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3045 if (fpos
< 0.0) fpos
= 0.0;
3046 m_oldVerticalPos
= fpos
;
3048 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3049 m_vAdjust
->value
= fpos
;
3054 if (m_wxwindow
->window
)
3056 if (orient
== wxHORIZONTAL
)
3057 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3059 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3064 int wxWindow::GetScrollThumb( int orient
) const
3066 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3068 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3070 if (orient
== wxHORIZONTAL
)
3071 return (int)(m_hAdjust
->page_size
+0.5);
3073 return (int)(m_vAdjust
->page_size
+0.5);
3076 int wxWindow::GetScrollPos( int orient
) const
3078 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3080 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3082 if (orient
== wxHORIZONTAL
)
3083 return (int)(m_hAdjust
->value
+0.5);
3085 return (int)(m_vAdjust
->value
+0.5);
3088 int wxWindow::GetScrollRange( int orient
) const
3090 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3092 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3094 if (orient
== wxHORIZONTAL
)
3095 return (int)(m_hAdjust
->upper
+0.5);
3097 return (int)(m_vAdjust
->upper
+0.5);
3100 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3102 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3104 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3108 GetClientSize( &cw
, &ch
);
3110 int w
= cw
- abs(dx
);
3111 int h
= ch
- abs(dy
);
3112 if ((h
< 0) || (w
< 0))
3119 if (dx
< 0) s_x
= -dx
;
3120 if (dy
< 0) s_y
= -dy
;
3123 if (dx
> 0) d_x
= dx
;
3124 if (dy
> 0) d_y
= dy
;
3128 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3129 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3132 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3133 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3136 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3137 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3138 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3139 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3141 Refresh( TRUE
, &rect
);
3144 //-------------------------------------------------------------------------------------
3146 //-------------------------------------------------------------------------------------
3148 wxLayoutConstraints
*wxWindow::GetConstraints() const
3150 return m_constraints
;
3153 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3157 UnsetConstraints(m_constraints
);
3158 delete m_constraints
;
3160 m_constraints
= constraints
;
3163 // Make sure other windows know they're part of a 'meaningful relationship'
3164 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3165 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3166 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3167 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3168 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3169 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3170 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3171 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3172 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3173 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3174 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3175 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3176 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3177 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3178 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3179 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3185 void wxWindow::SetAutoLayout( bool autoLayout
)
3187 m_autoLayout
= autoLayout
;
3190 bool wxWindow::GetAutoLayout() const
3192 return m_autoLayout
;
3195 wxSizer
*wxWindow::GetSizer() const
3197 return m_windowSizer
;
3200 void wxWindow::SetSizerParent( wxWindow
*win
)
3202 m_sizerParent
= win
;
3205 wxWindow
*wxWindow::GetSizerParent() const
3207 return m_sizerParent
;
3210 // This removes any dangling pointers to this window
3211 // in other windows' constraintsInvolvedIn lists.
3212 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3216 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3217 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3218 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3219 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3220 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3221 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3222 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3223 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3224 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3225 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3226 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3227 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3228 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3229 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3230 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3231 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3235 // Back-pointer to other windows we're involved with, so if we delete
3236 // this window, we must delete any constraints we're involved with.
3237 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3239 if (!m_constraintsInvolvedIn
)
3240 m_constraintsInvolvedIn
= new wxList
;
3241 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3242 m_constraintsInvolvedIn
->Append(otherWin
);
3245 // REMOVE back-pointer to other windows we're involved with.
3246 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3248 if (m_constraintsInvolvedIn
)
3249 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3252 // Reset any constraints that mention this window
3253 void wxWindow::DeleteRelatedConstraints()
3255 if (m_constraintsInvolvedIn
)
3257 wxNode
*node
= m_constraintsInvolvedIn
->First();
3260 wxWindow
*win
= (wxWindow
*)node
->Data();
3261 wxNode
*next
= node
->Next();
3262 wxLayoutConstraints
*constr
= win
->GetConstraints();
3264 // Reset any constraints involving this window
3267 constr
->left
.ResetIfWin((wxWindow
*)this);
3268 constr
->top
.ResetIfWin((wxWindow
*)this);
3269 constr
->right
.ResetIfWin((wxWindow
*)this);
3270 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3271 constr
->width
.ResetIfWin((wxWindow
*)this);
3272 constr
->height
.ResetIfWin((wxWindow
*)this);
3273 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3274 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3279 delete m_constraintsInvolvedIn
;
3280 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3284 void wxWindow::SetSizer(wxSizer
*sizer
)
3286 m_windowSizer
= sizer
;
3288 sizer
->SetSizerParent((wxWindow
*)this);
3295 bool wxWindow::Layout()
3297 if (GetConstraints())
3300 GetClientSize(&w
, &h
);
3301 GetConstraints()->width
.SetValue(w
);
3302 GetConstraints()->height
.SetValue(h
);
3305 // If top level (one sizer), evaluate the sizer's constraints.
3309 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3310 GetSizer()->LayoutPhase1(&noChanges
);
3311 GetSizer()->LayoutPhase2(&noChanges
);
3312 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3317 // Otherwise, evaluate child constraints
3318 ResetConstraints(); // Mark all constraints as unevaluated
3319 DoPhase(1); // Just one phase need if no sizers involved
3321 SetConstraintSizes(); // Recursively set the real window sizes
3327 // Do a phase of evaluating constraints:
3328 // the default behaviour. wxSizers may do a similar
3329 // thing, but also impose their own 'constraints'
3330 // and order the evaluation differently.
3331 bool wxWindow::LayoutPhase1(int *noChanges
)
3333 wxLayoutConstraints
*constr
= GetConstraints();
3336 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3342 bool wxWindow::LayoutPhase2(int *noChanges
)
3352 // Do a phase of evaluating child constraints
3353 bool wxWindow::DoPhase(int phase
)
3355 int noIterations
= 0;
3356 int maxIterations
= 500;
3360 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3364 wxNode
*node
= m_children
.First();
3367 wxWindow
*child
= (wxWindow
*)node
->Data();
3368 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3370 wxLayoutConstraints
*constr
= child
->GetConstraints();
3373 if (succeeded
.Member(child
))
3378 int tempNoChanges
= 0;
3379 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3380 noChanges
+= tempNoChanges
;
3383 succeeded
.Append(child
);
3388 node
= node
->Next();
3395 void wxWindow::ResetConstraints()
3397 wxLayoutConstraints
*constr
= GetConstraints();
3400 constr
->left
.SetDone(FALSE
);
3401 constr
->top
.SetDone(FALSE
);
3402 constr
->right
.SetDone(FALSE
);
3403 constr
->bottom
.SetDone(FALSE
);
3404 constr
->width
.SetDone(FALSE
);
3405 constr
->height
.SetDone(FALSE
);
3406 constr
->centreX
.SetDone(FALSE
);
3407 constr
->centreY
.SetDone(FALSE
);
3409 wxNode
*node
= m_children
.First();
3412 wxWindow
*win
= (wxWindow
*)node
->Data();
3413 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3414 win
->ResetConstraints();
3415 node
= node
->Next();
3419 // Need to distinguish between setting the 'fake' size for
3420 // windows and sizers, and setting the real values.
3421 void wxWindow::SetConstraintSizes(bool recurse
)
3423 wxLayoutConstraints
*constr
= GetConstraints();
3424 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3425 constr
->width
.GetDone() && constr
->height
.GetDone())
3427 int x
= constr
->left
.GetValue();
3428 int y
= constr
->top
.GetValue();
3429 int w
= constr
->width
.GetValue();
3430 int h
= constr
->height
.GetValue();
3432 // If we don't want to resize this window, just move it...
3433 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3434 (constr
->height
.GetRelationship() != wxAsIs
))
3436 // Calls Layout() recursively. AAAGH. How can we stop that.
3437 // Simply take Layout() out of non-top level OnSizes.
3438 SizerSetSize(x
, y
, w
, h
);
3447 char *windowClass
= this->GetClassInfo()->GetClassName();
3450 if (GetName() == "")
3451 winName
= "unnamed";
3453 winName
= GetName();
3454 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3455 (const char *)windowClass
,
3456 (const char *)winName
);
3457 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3458 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3459 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3460 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3461 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3466 wxNode
*node
= m_children
.First();
3469 wxWindow
*win
= (wxWindow
*)node
->Data();
3470 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3471 win
->SetConstraintSizes();
3472 node
= node
->Next();
3477 // This assumes that all sizers are 'on' the same
3478 // window, i.e. the parent of this window.
3479 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3481 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3482 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3486 m_sizerParent
->GetPosition(&xp
, &yp
);
3487 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3492 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3496 TransformSizerToActual(&xx
, &yy
);
3497 SetSize(xx
, yy
, w
, h
);
3500 void wxWindow::SizerMove(int x
, int y
)
3504 TransformSizerToActual(&xx
, &yy
);
3508 // Only set the size/position of the constraint (if any)
3509 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3511 wxLayoutConstraints
*constr
= GetConstraints();
3516 constr
->left
.SetValue(x
);
3517 constr
->left
.SetDone(TRUE
);
3521 constr
->top
.SetValue(y
);
3522 constr
->top
.SetDone(TRUE
);
3526 constr
->width
.SetValue(w
);
3527 constr
->width
.SetDone(TRUE
);
3531 constr
->height
.SetValue(h
);
3532 constr
->height
.SetDone(TRUE
);
3537 void wxWindow::MoveConstraint(int x
, int y
)
3539 wxLayoutConstraints
*constr
= GetConstraints();
3544 constr
->left
.SetValue(x
);
3545 constr
->left
.SetDone(TRUE
);
3549 constr
->top
.SetValue(y
);
3550 constr
->top
.SetDone(TRUE
);
3555 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3557 wxLayoutConstraints
*constr
= GetConstraints();
3560 *w
= constr
->width
.GetValue();
3561 *h
= constr
->height
.GetValue();
3567 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3569 wxLayoutConstraints
*constr
= GetConstraints();
3572 *w
= constr
->width
.GetValue();
3573 *h
= constr
->height
.GetValue();
3576 GetClientSize(w
, h
);
3579 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3581 wxLayoutConstraints
*constr
= GetConstraints();
3584 *x
= constr
->left
.GetValue();
3585 *y
= constr
->top
.GetValue();