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"
25 #if wxUSE_DRAG_AND_DROP
30 #include "wx/tooltip.h"
34 #include "wx/statusbr.h"
36 #include "wx/settings.h"
43 #include "gdk/gdkprivate.h"
44 #include "gdk/gdkkeysyms.h"
45 #include "wx/gtk/win_gtk.h"
47 //-----------------------------------------------------------------------------
48 // documentation on internals
49 //-----------------------------------------------------------------------------
52 I have been asked several times about writing some documentation about
53 the GTK port of wxWindows, especially its internal structures. Obviously,
54 you cannot understand wxGTK without knowing a little about the GTK, but
55 some more information about what the wxWindow, which is the base class
56 for all other window classes, does seems required as well.
58 What does wxWindow do? It contains the common interface for the following
59 jobs of its descendants:
61 1) Define the rudimentary behaviour common to all window classes, such as
62 resizing, intercepting user input (so as to make it possible to use these
63 events for special purposes in a derived class), window names etc.
65 2) Provide the possibility to contain and manage children, if the derived
66 class is allowed to contain children, which holds true for those window
67 classes which do not display a native GTK widget. To name them, these
68 classes are wxPanel, wxScrolledWindow, wxDialog, wxFrame. The MDI frame-
69 work classes are a special case and are handled a bit differently from
70 the rest. The same holds true for the wxNotebook class.
72 3) Provide the possibility to draw into a client area of a window. This,
73 too, only holds true for classes that do not display a native GTK widget
76 4) Provide the entire mechanism for scrolling widgets. This actual inter-
77 face for this is usually in wxScrolledWindow, but the GTK implementation
80 5) A multitude of helper or extra methods for special purposes, such as
81 Drag'n'Drop, managing validators etc.
83 Normally one might expect, that one wxWindows window would always correspond
84 to one GTK widget. Under GTK, there is no such allround widget that has all
85 the functionality. Moreover, the GTK defines a client area as a different
86 widget from the actual widget you are handling. Last but not least some
87 special classes (e.g. wxFrame) handle different categories of widgets and
88 still have the possibility to draw something in the client area.
89 It was therefore required to write a special purpose GTK widget, that would
90 represent a client area in the sense of wxWindows capable to do the jobs
91 2), 3) and 4). I have written this class and it resides in win_gtk.c of
94 All windows must have a widget, with which they interact with other under-
95 lying GTK widgets. It is this widget, e.g. that has to be resized etc and
96 thw wxWindow class has a member variable called m_widget which holds a
97 pointer to this widget. When the window class represents a GTK native widget,
98 this is (in most cases) the only GTK widget the class manages. E.g. the
99 wxStatitText class handles only a GtkLabel widget a pointer to which you
100 can find in m_widget (defined in wxWindow)
102 When the class has a client area for drawing into and for containing children
103 it has to handle the client area widget (of the type GtkMyFixed, defined in
104 win_gtk.c), but there could be any number of widgets, handled by a class
105 The common rule for all windows is only, that the widget that interacts with
106 the rest of GTK must be referenced in m_widget and all other widgets must be
107 children of this widget on the GTK level. The top-most widget, which also
108 represents the client area, must be in the m_wxwindow field and must be of
111 As I said, the window classes that display a GTK native widget only have
112 one widget, so in the case of e.g. the wxButton class m_widget holds a
113 pointer to a GtkButton widget. But windows with client areas (for drawing
114 and children) have a m_widget field that is a pointer to a GtkScrolled-
115 Window and a m_wxwindow field that is pointer to a GtkMyFixed and this
116 one is (in the GTK sense) a child of the GtkScrolledWindow.
118 If the m_wxwindow field is set, then all input to this widget is inter-
119 cepted and sent to the wxWindows class. If not, all input to the widget
120 that gets pointed to by m_widget gets intercepted and sent to the class.
124 //-----------------------------------------------------------------------------
126 //-----------------------------------------------------------------------------
130 static gint
gtk_debug_focus_in_callback( GtkWidget
*WXUNUSED(widget
),
131 GdkEvent
*WXUNUSED(event
),
134 // to enable logging of the focus events replace 0 with 1
136 static bool s_done
= FALSE
;
139 wxLog::AddTraceMask("focus");
143 wxLogTrace(_T("FOCUS NOW AT: %s"), name
);
148 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
154 wxChar
*s
= new wxChar
[tmp
.Length()+1];
158 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
159 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
164 //-----------------------------------------------------------------------------
166 //-----------------------------------------------------------------------------
168 extern wxList wxPendingDelete
;
169 extern bool g_blockEventsOnDrag
;
170 extern bool g_blockEventsOnScroll
;
171 extern bool g_isIdle
;
172 static bool g_capturing
= FALSE
;
173 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
175 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
176 the last click here */
177 static guint32 gs_timeLastClick
= 0;
179 //-----------------------------------------------------------------------------
181 //-----------------------------------------------------------------------------
183 extern void wxapp_install_idle_handler();
184 extern bool g_isIdle
;
186 #if (GTK_MINOR_VERSION > 0)
188 //-----------------------------------------------------------------------------
189 // local code (see below)
190 //-----------------------------------------------------------------------------
192 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
194 if (!win
->HasVMT()) return;
199 if (win
->m_hasScrolling
)
201 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
202 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
205 GtkWidget *hscrollbar = scroll_window->hscrollbar;
206 GtkWidget *vscrollbar = scroll_window->vscrollbar;
208 we use this instead: range.slider_width = 11 + 2*2pts edge
211 if (scroll_window
->vscrollbar_visible
)
213 dw
+= 15; /* dw += vscrollbar->allocation.width; */
214 dw
+= scroll_class
->scrollbar_spacing
;
217 if (scroll_window
->hscrollbar_visible
)
219 dh
+= 15; /* dh += hscrollbar->allocation.height; */
220 dw
+= scroll_class
->scrollbar_spacing
;
226 if (GTK_WIDGET_NO_WINDOW (widget
))
228 dx
+= widget
->allocation
.x
;
229 dy
+= widget
->allocation
.y
;
232 if (win
->m_windowStyle
& wxRAISED_BORDER
)
234 gtk_draw_shadow( widget
->style
,
239 win
->m_width
-dw
, win
->m_height
-dh
);
243 if (win
->m_windowStyle
& wxSUNKEN_BORDER
)
245 gtk_draw_shadow( widget
->style
,
250 win
->m_width
-dw
, win
->m_height
-dh
);
255 //-----------------------------------------------------------------------------
256 // "expose_event" of m_widget
257 //-----------------------------------------------------------------------------
259 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
261 if (gdk_event
->count
> 0) return;
262 draw_frame( widget
, win
);
265 //-----------------------------------------------------------------------------
266 // "draw" of m_wxwindow
267 //-----------------------------------------------------------------------------
269 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
271 draw_frame( widget
, win
);
276 //-----------------------------------------------------------------------------
277 // "expose_event" of m_wxwindow
278 //-----------------------------------------------------------------------------
280 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
282 if (g_isIdle
) wxapp_install_idle_handler();
284 if (!win
->HasVMT()) return;
286 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
288 gdk_event
->area
.width
,
289 gdk_event
->area
.height
);
291 if (gdk_event
->count
> 0) return;
294 printf( "OnExpose from " );
295 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
296 printf( win->GetClassInfo()->GetClassName() );
300 wxPaintEvent
event( win
->GetId() );
301 event
.SetEventObject( win
);
302 win
->GetEventHandler()->ProcessEvent( event
);
304 win
->m_updateRegion
.Clear();
307 //-----------------------------------------------------------------------------
308 // "draw" of m_wxwindow
309 //-----------------------------------------------------------------------------
311 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
313 if (g_isIdle
) wxapp_install_idle_handler();
315 if (!win
->HasVMT()) return;
317 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
319 wxPaintEvent
event( win
->GetId() );
320 event
.SetEventObject( win
);
321 win
->GetEventHandler()->ProcessEvent( event
);
323 win
->m_updateRegion
.Clear();
326 //-----------------------------------------------------------------------------
327 // "key_press_event" from any window
328 //-----------------------------------------------------------------------------
330 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
332 if (g_isIdle
) wxapp_install_idle_handler();
334 if (!win
->HasVMT()) return FALSE
;
335 if (g_blockEventsOnDrag
) return FALSE
;
338 wxPrintf( _T("OnKeyPress from ") );
339 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
340 wxPrintf( win->GetClassInfo()->GetClassName() );
341 wxPrintf( _T(".\n") );
345 switch (gdk_event
->keyval
)
347 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
348 case GDK_ISO_Left_Tab
:
350 case GDK_Tab
: key_code
= WXK_TAB
; break;
351 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
352 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
353 case GDK_Return
: key_code
= WXK_RETURN
; break;
354 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
355 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
356 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
357 case GDK_Delete
: key_code
= WXK_DELETE
; break;
358 case GDK_Home
: key_code
= WXK_HOME
; break;
359 case GDK_Left
: key_code
= WXK_LEFT
; break;
360 case GDK_Up
: key_code
= WXK_UP
; break;
361 case GDK_Right
: key_code
= WXK_RIGHT
; break;
362 case GDK_Down
: key_code
= WXK_DOWN
; break;
363 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
364 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
365 case GDK_Next
: key_code
= WXK_NEXT
; break;
366 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
367 case GDK_End
: key_code
= WXK_END
; break;
368 case GDK_Begin
: key_code
= WXK_HOME
; break;
369 case GDK_Select
: key_code
= WXK_SELECT
; break;
370 case GDK_Print
: key_code
= WXK_PRINT
; break;
371 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
372 case GDK_Insert
: key_code
= WXK_INSERT
; break;
373 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
374 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
375 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
376 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
377 case GDK_KP_Up
: key_code
= WXK_UP
; break;
378 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
379 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
380 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
381 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
382 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
383 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
384 case GDK_KP_End
: key_code
= WXK_END
; break;
385 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
386 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
387 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
388 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
389 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
390 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
391 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
392 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
393 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
394 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
395 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
396 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
397 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
398 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
399 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
400 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
401 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
402 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
403 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
404 case GDK_F1
: key_code
= WXK_F1
; break;
405 case GDK_F2
: key_code
= WXK_F2
; break;
406 case GDK_F3
: key_code
= WXK_F3
; break;
407 case GDK_F4
: key_code
= WXK_F4
; break;
408 case GDK_F5
: key_code
= WXK_F5
; break;
409 case GDK_F6
: key_code
= WXK_F6
; break;
410 case GDK_F7
: key_code
= WXK_F7
; break;
411 case GDK_F8
: key_code
= WXK_F8
; break;
412 case GDK_F9
: key_code
= WXK_F9
; break;
413 case GDK_F10
: key_code
= WXK_F10
; break;
414 case GDK_F11
: key_code
= WXK_F11
; break;
415 case GDK_F12
: key_code
= WXK_F12
; break;
418 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
419 key_code
= gdk_event
->keyval
;
423 if (!key_code
) return FALSE
;
425 wxKeyEvent
event( wxEVT_KEY_DOWN
);
426 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
427 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
428 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
429 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
430 event
.m_keyCode
= key_code
;
433 event
.SetEventObject( win
);
435 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
439 wxWindow
*ancestor
= win
;
442 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
445 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
446 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
449 ancestor
= ancestor
->GetParent();
453 // win is a control: tab can be propagated up
455 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
456 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
458 wxNavigationKeyEvent new_event
;
459 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
460 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
461 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
462 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
463 new_event
.SetCurrentFocus( win
);
464 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
468 (gdk_event
->keyval
== GDK_Escape
) )
470 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
471 new_event
.SetEventObject( win
);
472 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
476 Damn, I forgot why this didn't work, but it didn't work.
478 // win is a panel: up can be propagated to the panel
479 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
480 (gdk_event->keyval == GDK_Up))
482 win->m_parent->SetFocus();
486 // win is a panel: left/right can be propagated to the panel
487 if ((!ret) && (win->m_wxwindow) &&
488 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
489 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
491 wxNavigationKeyEvent new_event;
492 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
493 new_event.SetCurrentFocus( win );
494 ret = win->GetEventHandler()->ProcessEvent( new_event );
500 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
507 //-----------------------------------------------------------------------------
508 // "key_release_event" from any window
509 //-----------------------------------------------------------------------------
511 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
513 if (g_isIdle
) wxapp_install_idle_handler();
515 if (!win
->HasVMT()) return FALSE
;
516 if (g_blockEventsOnDrag
) return FALSE
;
519 printf( "OnKeyRelease from " );
520 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
521 printf( win->GetClassInfo()->GetClassName() );
526 switch (gdk_event
->keyval
)
528 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
529 case GDK_ISO_Left_Tab
:
531 case GDK_Tab
: key_code
= WXK_TAB
; break;
532 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
533 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
534 case GDK_Return
: key_code
= WXK_RETURN
; break;
535 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
536 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
537 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
538 case GDK_Delete
: key_code
= WXK_DELETE
; break;
539 case GDK_Home
: key_code
= WXK_HOME
; break;
540 case GDK_Left
: key_code
= WXK_LEFT
; break;
541 case GDK_Up
: key_code
= WXK_UP
; break;
542 case GDK_Right
: key_code
= WXK_RIGHT
; break;
543 case GDK_Down
: key_code
= WXK_DOWN
; break;
544 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
545 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
546 case GDK_Next
: key_code
= WXK_NEXT
; break;
547 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
548 case GDK_End
: key_code
= WXK_END
; break;
549 case GDK_Begin
: key_code
= WXK_HOME
; break;
550 case GDK_Select
: key_code
= WXK_SELECT
; break;
551 case GDK_Print
: key_code
= WXK_PRINT
; break;
552 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
553 case GDK_Insert
: key_code
= WXK_INSERT
; break;
554 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
555 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
556 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
557 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
558 case GDK_KP_Up
: key_code
= WXK_UP
; break;
559 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
560 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
561 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
562 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
563 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
564 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
565 case GDK_KP_End
: key_code
= WXK_END
; break;
566 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
567 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
568 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
569 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
570 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
571 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
572 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
573 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
574 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
575 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
576 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
577 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
578 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
579 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
580 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
581 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
582 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
583 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
584 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
585 case GDK_F1
: key_code
= WXK_F1
; break;
586 case GDK_F2
: key_code
= WXK_F2
; break;
587 case GDK_F3
: key_code
= WXK_F3
; break;
588 case GDK_F4
: key_code
= WXK_F4
; break;
589 case GDK_F5
: key_code
= WXK_F5
; break;
590 case GDK_F6
: key_code
= WXK_F6
; break;
591 case GDK_F7
: key_code
= WXK_F7
; break;
592 case GDK_F8
: key_code
= WXK_F8
; break;
593 case GDK_F9
: key_code
= WXK_F9
; break;
594 case GDK_F10
: key_code
= WXK_F10
; break;
595 case GDK_F11
: key_code
= WXK_F11
; break;
596 case GDK_F12
: key_code
= WXK_F12
; break;
599 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
600 key_code
= gdk_event
->keyval
;
604 if (!key_code
) return FALSE
;
606 wxKeyEvent
event( wxEVT_KEY_UP
);
607 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
608 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
609 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
610 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
611 event
.m_keyCode
= key_code
;
614 event
.SetEventObject( win
);
616 if (win
->GetEventHandler()->ProcessEvent( event
))
618 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
625 //-----------------------------------------------------------------------------
626 // "button_press_event"
627 //-----------------------------------------------------------------------------
629 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
631 if (g_isIdle
) wxapp_install_idle_handler();
634 wxPrintf( _T("1) OnButtonPress from ") );
635 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
636 wxPrintf( win->GetClassInfo()->GetClassName() );
637 wxPrintf( _T(".\n") );
640 if (!win
->HasVMT()) return FALSE
;
641 if (g_blockEventsOnDrag
) return TRUE
;
642 if (g_blockEventsOnScroll
) return TRUE
;
644 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
648 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
650 gtk_widget_grab_focus (win
->m_wxwindow
);
653 wxPrintf( _T("GrabFocus from ") );
654 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
655 wxPrintf( win->GetClassInfo()->GetClassName() );
656 wxPrintf( _T(".\n") );
663 wxPrintf( _T("No GrabFocus from ") );
664 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
665 wxPrintf( win->GetClassInfo()->GetClassName() );
666 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
667 wxPrintf( _T(" because it already has") );
668 wxPrintf( _T(".\n") );
674 wxPrintf( _T("2) OnButtonPress from ") );
675 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
676 wxPrintf( win->GetClassInfo()->GetClassName() );
677 wxPrintf( _T(".\n") );
680 wxEventType event_type
= wxEVT_LEFT_DOWN
;
682 if (gdk_event
->button
== 1)
684 switch (gdk_event
->type
)
686 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
687 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
691 else if (gdk_event
->button
== 2)
693 switch (gdk_event
->type
)
695 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
696 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
700 else if (gdk_event
->button
== 3)
702 switch (gdk_event
->type
)
704 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
705 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
710 wxMouseEvent
event( event_type
);
711 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
712 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
713 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
714 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
715 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
716 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
717 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
719 event
.m_x
= (long)gdk_event
->x
;
720 event
.m_y
= (long)gdk_event
->y
;
722 // Some control don't have their own X window and thus cannot get
727 wxNode
*node
= win
->GetChildren().First();
730 wxWindow
*child
= (wxWindow
*)node
->Data();
732 if (child
->m_isStaticBox
)
734 // wxStaticBox is transparent in the box itself
737 int xx1
= child
->m_x
;
738 int yy1
= child
->m_y
;
739 int xx2
= child
->m_x
+ child
->m_width
;
740 int yy2
= child
->m_x
+ child
->m_height
;
743 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
745 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
747 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
749 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
752 event
.m_x
-= child
->m_x
;
753 event
.m_y
-= child
->m_y
;
760 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
761 (child
->m_x
<= event
.m_x
) &&
762 (child
->m_y
<= event
.m_y
) &&
763 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
764 (child
->m_y
+child
->m_height
>= event
.m_y
))
767 event
.m_x
-= child
->m_x
;
768 event
.m_y
-= child
->m_y
;
776 event
.SetEventObject( win
);
778 gs_timeLastClick
= gdk_event
->time
;
780 if (win
->GetEventHandler()->ProcessEvent( event
))
782 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
789 //-----------------------------------------------------------------------------
790 // "button_release_event"
791 //-----------------------------------------------------------------------------
793 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
795 if (g_isIdle
) wxapp_install_idle_handler();
797 if (!win
->HasVMT()) return FALSE
;
798 if (g_blockEventsOnDrag
) return FALSE
;
799 if (g_blockEventsOnScroll
) return FALSE
;
801 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
804 printf( "OnButtonRelease from " );
805 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
806 printf( win->GetClassInfo()->GetClassName() );
810 wxEventType event_type
= wxEVT_NULL
;
812 switch (gdk_event
->button
)
814 case 1: event_type
= wxEVT_LEFT_UP
; break;
815 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
816 case 3: event_type
= wxEVT_RIGHT_UP
; break;
819 wxMouseEvent
event( event_type
);
820 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
821 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
822 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
823 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
824 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
825 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
826 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
827 event
.m_x
= (long)gdk_event
->x
;
828 event
.m_y
= (long)gdk_event
->y
;
830 // Some control don't have their own X window and thus cannot get
835 wxNode
*node
= win
->GetChildren().First();
838 wxWindow
*child
= (wxWindow
*)node
->Data();
840 if (child
->m_isStaticBox
)
842 // wxStaticBox is transparent in the box itself
845 int xx1
= child
->m_x
;
846 int yy1
= child
->m_y
;
847 int xx2
= child
->m_x
+ child
->m_width
;
848 int yy2
= child
->m_x
+ child
->m_height
;
851 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
853 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
855 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
857 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
860 event
.m_x
-= child
->m_x
;
861 event
.m_y
-= child
->m_y
;
868 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
869 (child
->m_x
<= event
.m_x
) &&
870 (child
->m_y
<= event
.m_y
) &&
871 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
872 (child
->m_y
+child
->m_height
>= event
.m_y
))
875 event
.m_x
-= child
->m_x
;
876 event
.m_y
-= child
->m_y
;
884 event
.SetEventObject( win
);
886 if (win
->GetEventHandler()->ProcessEvent( event
))
888 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
895 //-----------------------------------------------------------------------------
896 // "motion_notify_event"
897 //-----------------------------------------------------------------------------
899 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
901 if (g_isIdle
) wxapp_install_idle_handler();
903 if (!win
->HasVMT()) return FALSE
;
904 if (g_blockEventsOnDrag
) return FALSE
;
905 if (g_blockEventsOnScroll
) return FALSE
;
907 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
909 if (gdk_event
->is_hint
)
913 GdkModifierType state
;
914 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
917 gdk_event
->state
= state
;
921 printf( "OnMotion from " );
922 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
923 printf( win->GetClassInfo()->GetClassName() );
927 wxMouseEvent
event( wxEVT_MOTION
);
928 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
929 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
930 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
931 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
932 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
933 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
934 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
936 event
.m_x
= (long)gdk_event
->x
;
937 event
.m_y
= (long)gdk_event
->y
;
939 // Some control don't have their own X window and thus cannot get
944 wxNode
*node
= win
->GetChildren().First();
947 wxWindow
*child
= (wxWindow
*)node
->Data();
949 if (child
->m_isStaticBox
)
951 // wxStaticBox is transparent in the box itself
954 int xx1
= child
->m_x
;
955 int yy1
= child
->m_y
;
956 int xx2
= child
->m_x
+ child
->m_width
;
957 int yy2
= child
->m_x
+ child
->m_height
;
960 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
962 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
964 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
966 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
969 event
.m_x
-= child
->m_x
;
970 event
.m_y
-= child
->m_y
;
977 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
978 (child
->m_x
<= event
.m_x
) &&
979 (child
->m_y
<= event
.m_y
) &&
980 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
981 (child
->m_y
+child
->m_height
>= event
.m_y
))
984 event
.m_x
-= child
->m_x
;
985 event
.m_y
-= child
->m_y
;
993 event
.SetEventObject( win
);
995 if (win
->GetEventHandler()->ProcessEvent( event
))
997 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
1004 //-----------------------------------------------------------------------------
1006 //-----------------------------------------------------------------------------
1008 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1010 if (g_isIdle
) wxapp_install_idle_handler();
1012 if (!win
->HasVMT()) return FALSE
;
1013 if (g_blockEventsOnDrag
) return FALSE
;
1015 g_focusWindow
= win
;
1017 if (win
->m_wxwindow
)
1019 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1021 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1023 printf( "SetFocus flag from " );
1024 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1025 printf( win->GetClassInfo()->GetClassName() );
1033 wxPrintf( _T("OnSetFocus from ") );
1034 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1035 wxPrintf( win->GetClassInfo()->GetClassName() );
1036 wxPrintf( _T(" ") );
1037 wxPrintf( win->GetLabel() );
1038 wxPrintf( _T(".\n") );
1041 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1042 event
.SetEventObject( win
);
1044 if (win
->GetEventHandler()->ProcessEvent( event
))
1046 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1053 //-----------------------------------------------------------------------------
1054 // "focus_out_event"
1055 //-----------------------------------------------------------------------------
1057 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1059 if (g_isIdle
) wxapp_install_idle_handler();
1061 if (!win
->HasVMT()) return FALSE
;
1062 if (g_blockEventsOnDrag
) return FALSE
;
1064 if (win
->m_wxwindow
)
1066 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1067 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1071 wxPrintf( _T("OnKillFocus from ") );
1072 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1073 wxPrintf( win->GetClassInfo()->GetClassName() );
1074 wxPrintf( _T(" ") );
1075 wxPrintf( win->GetLabel() );
1076 wxPrintf( _T(".\n") );
1079 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1080 event
.SetEventObject( win
);
1082 if (win
->GetEventHandler()->ProcessEvent( event
))
1084 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1091 //-----------------------------------------------------------------------------
1092 // "enter_notify_event"
1093 //-----------------------------------------------------------------------------
1095 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1097 if (g_isIdle
) wxapp_install_idle_handler();
1099 if (!win
->HasVMT()) return FALSE
;
1100 if (g_blockEventsOnDrag
) return FALSE
;
1102 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1104 if ((widget
->window
) && (win
->m_cursor
.Ok()))
1105 gdk_window_set_cursor( widget
->window
, win
->m_cursor
.GetCursor() );
1108 printf( "OnEnter from " );
1109 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1110 printf( win->GetClassInfo()->GetClassName() );
1114 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1115 event
.SetEventObject( win
);
1119 GdkModifierType state
= (GdkModifierType
)0;
1121 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1123 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1124 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1125 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1126 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1127 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1128 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1129 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1131 event
.m_x
= (long)x
;
1132 event
.m_y
= (long)y
;
1134 if (win
->GetEventHandler()->ProcessEvent( event
))
1136 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1143 //-----------------------------------------------------------------------------
1144 // "leave_notify_event"
1145 //-----------------------------------------------------------------------------
1147 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1149 if (g_isIdle
) wxapp_install_idle_handler();
1151 if (!win
->HasVMT()) return FALSE
;
1152 if (g_blockEventsOnDrag
) return FALSE
;
1154 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
1157 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1160 wxPrintf( _T("OnLeave from ") );
1161 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1162 wxPrintf( win->GetClassInfo()->GetClassName() );
1163 wxPrintf( _T(".\n") );
1166 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1167 event
.SetEventObject( win
);
1171 GdkModifierType state
= (GdkModifierType
)0;
1173 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1175 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1176 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1177 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1178 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1179 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1180 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1181 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1183 event
.m_x
= (long)x
;
1184 event
.m_y
= (long)y
;
1186 if (win
->GetEventHandler()->ProcessEvent( event
))
1188 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1195 //-----------------------------------------------------------------------------
1196 // "value_changed" from m_vAdjust
1197 //-----------------------------------------------------------------------------
1199 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1201 if (g_isIdle
) wxapp_install_idle_handler();
1203 if (g_blockEventsOnDrag
) return;
1206 printf( "OnVScroll from " );
1207 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1208 printf( win->GetClassInfo()->GetClassName() );
1212 if (!win
->HasVMT()) return;
1214 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1215 if (fabs(diff
) < 0.2) return;
1216 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1218 wxEventType command
= wxEVT_NULL
;
1220 float line_step
= win
->m_vAdjust
->step_increment
;
1221 float page_step
= win
->m_vAdjust
->page_increment
;
1223 if (win
->m_isScrolling
)
1225 command
= wxEVT_SCROLL_THUMBTRACK
;
1229 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1230 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1231 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1232 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1233 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1234 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1235 else command
= wxEVT_SCROLL_THUMBTRACK
;
1238 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1240 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1241 event
.SetEventObject( win
);
1242 win
->GetEventHandler()->ProcessEvent( event
);
1245 //-----------------------------------------------------------------------------
1246 // "value_changed" from m_hAdjust
1247 //-----------------------------------------------------------------------------
1249 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1251 if (g_isIdle
) wxapp_install_idle_handler();
1253 if (g_blockEventsOnDrag
) return;
1256 printf( "OnHScroll from " );
1257 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1258 printf( win->GetClassInfo()->GetClassName() );
1262 if (!win
->HasVMT()) return;
1264 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1265 if (fabs(diff
) < 0.2) return;
1266 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1268 wxEventType command
= wxEVT_NULL
;
1270 float line_step
= win
->m_hAdjust
->step_increment
;
1271 float page_step
= win
->m_hAdjust
->page_increment
;
1273 if (win
->m_isScrolling
)
1275 command
= wxEVT_SCROLL_THUMBTRACK
;
1279 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1280 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1281 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1282 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1283 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1284 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1285 else command
= wxEVT_SCROLL_THUMBTRACK
;
1288 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1290 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1291 event
.SetEventObject( win
);
1292 win
->GetEventHandler()->ProcessEvent( event
);
1295 //-----------------------------------------------------------------------------
1296 // "changed" from m_vAdjust
1297 //-----------------------------------------------------------------------------
1299 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1301 if (g_isIdle
) wxapp_install_idle_handler();
1303 if (g_blockEventsOnDrag
) return;
1306 printf( "OnVScroll change from " );
1307 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1308 printf( win->GetClassInfo()->GetClassName() );
1312 if (!win
->HasVMT()) return;
1314 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1315 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1317 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1318 event
.SetEventObject( win
);
1319 win
->GetEventHandler()->ProcessEvent( event
);
1322 //-----------------------------------------------------------------------------
1323 // "changed" from m_hAdjust
1324 //-----------------------------------------------------------------------------
1326 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1328 if (g_isIdle
) wxapp_install_idle_handler();
1330 if (g_blockEventsOnDrag
) return;
1333 printf( "OnHScroll change from " );
1334 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1335 printf( win->GetClassInfo()->GetClassName() );
1339 if (!win
->HasVMT()) return;
1341 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1342 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1344 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1345 event
.SetEventObject( win
);
1346 win
->GetEventHandler()->ProcessEvent( event
);
1349 //-----------------------------------------------------------------------------
1350 // "button_press_event" from scrollbar
1351 //-----------------------------------------------------------------------------
1353 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1354 GdkEventButton
*WXUNUSED(gdk_event
),
1357 if (g_isIdle
) wxapp_install_idle_handler();
1359 // don't test here as we can release the mouse while being over
1360 // a different window then the slider
1362 // if (gdk_event->window != widget->slider) return FALSE;
1364 win
->m_isScrolling
= TRUE
;
1365 g_blockEventsOnScroll
= TRUE
;
1370 //-----------------------------------------------------------------------------
1371 // "button_release_event" from scrollbar
1372 //-----------------------------------------------------------------------------
1374 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1375 GdkEventButton
*WXUNUSED(gdk_event
),
1378 if (g_isIdle
) wxapp_install_idle_handler();
1380 // don't test here as we can release the mouse while being over
1381 // a different window then the slider
1383 // if (gdk_event->window != widget->slider) return FALSE;
1385 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1387 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1388 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1390 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1392 win
->m_isScrolling
= FALSE
;
1393 g_blockEventsOnScroll
= FALSE
;
1398 //-----------------------------------------------------------------------------
1399 // "realize" from m_widget
1400 //-----------------------------------------------------------------------------
1402 /* we cannot set colours, fonts and cursors before the widget has
1403 been realized, so we do this directly after realization */
1406 gtk_window_realized_callback( GtkWidget
*widget
, wxWindow
*win
)
1408 if (g_isIdle
) wxapp_install_idle_handler();
1410 if (win
->m_font
!= *wxSWISS_FONT
)
1412 wxFont
font( win
->m_font
);
1413 win
->m_font
= wxNullFont
;
1414 win
->SetFont( font
);
1417 if (win
->m_backgroundColour
!= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
))
1419 wxColour
bg( win
->m_backgroundColour
);
1420 win
->m_backgroundColour
= wxNullColour
;
1421 win
->SetBackgroundColour( bg
);
1424 if (win
->m_foregroundColour
!= *wxBLACK
)
1426 wxColour
fg( win
->m_foregroundColour
);
1427 win
->m_foregroundColour
= wxNullColour
;
1428 win
->SetForegroundColour( fg
);
1431 wxCursor
cursor( win
->m_cursor
);
1432 win
->m_cursor
= wxNullCursor
;
1433 win
->SetCursor( cursor
);
1438 //-----------------------------------------------------------------------------
1439 // InsertChild for wxWindow.
1440 //-----------------------------------------------------------------------------
1442 /* Callback for wxWindow. This very strange beast has to be used because
1443 * C++ has no virtual methods in a constructor. We have to emulate a
1444 * virtual function here as wxNotebook requires a different way to insert
1445 * a child in it. I had opted for creating a wxNotebookPage window class
1446 * which would have made this superfluous (such in the MDI window system),
1447 * but no-one was listening to me... */
1449 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1451 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1452 GTK_WIDGET(child
->m_widget
),
1458 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1460 /* we now allow a window to get the focus as long as it
1461 doesn't have any children. */
1462 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1466 //-----------------------------------------------------------------------------
1468 //-----------------------------------------------------------------------------
1470 wxWindow
* wxGetActiveWindow()
1472 return g_focusWindow
;
1475 //-----------------------------------------------------------------------------
1477 //-----------------------------------------------------------------------------
1479 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1481 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1482 EVT_SIZE(wxWindow::OnSize
)
1483 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1484 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1485 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1488 void wxWindow::Init()
1492 m_widget
= (GtkWidget
*) NULL
;
1493 m_wxwindow
= (GtkWidget
*) NULL
;
1494 m_parent
= (wxWindow
*) NULL
;
1495 m_children
.DeleteContents( FALSE
);
1508 m_eventHandler
= this;
1509 m_windowValidator
= (wxValidator
*) NULL
;
1513 m_cursor
= *wxSTANDARD_CURSOR
;
1514 m_font
= *wxSWISS_FONT
;
1516 m_windowName
= "noname";
1518 m_constraints
= (wxLayoutConstraints
*) NULL
;
1519 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1520 m_windowSizer
= (wxSizer
*) NULL
;
1521 m_sizerParent
= (wxWindow
*) NULL
;
1522 m_autoLayout
= FALSE
;
1526 m_needParent
= TRUE
;
1528 m_hasScrolling
= FALSE
;
1529 m_isScrolling
= FALSE
;
1530 m_hAdjust
= (GtkAdjustment
*) NULL
;
1531 m_vAdjust
= (GtkAdjustment
*) NULL
;
1532 m_oldHorizontalPos
= 0.0;
1533 m_oldVerticalPos
= 0.0;
1538 #if wxUSE_DRAG_AND_DROP
1539 m_dropTarget
= (wxDropTarget
*) NULL
;
1542 m_scrollGC
= (GdkGC
*) NULL
;
1543 m_widgetStyle
= (GtkStyle
*) NULL
;
1545 m_insertCallback
= wxInsertChildInWindow
;
1547 m_clientObject
= (wxClientData
*) NULL
;
1548 m_clientData
= NULL
;
1550 m_isStaticBox
= FALSE
;
1551 m_acceptsFocus
= FALSE
;
1554 m_toolTip
= (wxToolTip
*) NULL
;
1555 #endif // wxUSE_TOOLTIPS
1558 wxWindow::wxWindow()
1563 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1564 const wxPoint
&pos
, const wxSize
&size
,
1565 long style
, const wxString
&name
)
1569 Create( parent
, id
, pos
, size
, style
, name
);
1572 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1573 const wxPoint
&pos
, const wxSize
&size
,
1574 long style
, const wxString
&name
)
1576 wxASSERT_MSG( m_isWindow
, _T("Init() must have been called before!") );
1578 PreCreation( parent
, id
, pos
, size
, style
, name
);
1580 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1581 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1584 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1587 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1590 debug_focus_in( s_window
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1591 debug_focus_in( s_window
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1594 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1595 scroll_class
->scrollbar_spacing
= 0;
1597 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1599 m_oldHorizontalPos
= 0.0;
1600 m_oldVerticalPos
= 0.0;
1602 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1603 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1605 m_wxwindow
= gtk_myfixed_new();
1608 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1611 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1613 #if (GTK_MINOR_VERSION > 0)
1614 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1616 if (m_windowStyle
& wxRAISED_BORDER
)
1618 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1620 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1622 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1626 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1629 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1631 if (m_windowStyle
& wxRAISED_BORDER
)
1633 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1635 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1637 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1641 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1645 /* we always allow a window to get the focus as long as it
1646 doesn't have any children. */
1647 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1649 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1650 m_acceptsFocus
= FALSE
;
1654 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1655 m_acceptsFocus
= TRUE
;
1658 /* grab the actual focus */
1659 // gtk_widget_grab_focus( m_wxwindow );
1661 gtk_widget_show( m_wxwindow
);
1664 #if (GTK_MINOR_VERSION == 0)
1665 // shut the viewport up
1666 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1667 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1670 // I _really_ don't want scrollbars in the beginning
1671 m_vAdjust
->lower
= 0.0;
1672 m_vAdjust
->upper
= 1.0;
1673 m_vAdjust
->value
= 0.0;
1674 m_vAdjust
->step_increment
= 1.0;
1675 m_vAdjust
->page_increment
= 1.0;
1676 m_vAdjust
->page_size
= 5.0;
1677 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1678 m_hAdjust
->lower
= 0.0;
1679 m_hAdjust
->upper
= 1.0;
1680 m_hAdjust
->value
= 0.0;
1681 m_hAdjust
->step_increment
= 1.0;
1682 m_hAdjust
->page_increment
= 1.0;
1683 m_hAdjust
->page_size
= 5.0;
1684 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1686 // these handlers block mouse events to any window during scrolling
1687 // such as motion events and prevent GTK and wxWindows from fighting
1688 // over where the slider should be
1690 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1691 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1693 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1694 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1696 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1697 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1699 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1700 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1702 // these handlers get notified when screen updates are required either when
1703 // scrolling or when the window size (and therefore scrollbar configuration)
1706 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1707 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1708 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1709 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1711 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1712 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1713 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1714 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1716 if (m_parent
) m_parent
->AddChild( this );
1718 (m_parent
->m_insertCallback
)( m_parent
, this );
1727 wxWindow::~wxWindow()
1731 #if wxUSE_DRAG_AND_DROP
1734 delete m_dropTarget
;
1735 m_dropTarget
= (wxDropTarget
*) NULL
;
1743 m_toolTip
= (wxToolTip
*) NULL
;
1745 #endif // wxUSE_TOOLTIPS
1747 if (m_widget
) Show( FALSE
);
1751 if (m_parent
) m_parent
->RemoveChild( this );
1753 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1755 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1757 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1759 if (m_widget
) gtk_widget_destroy( m_widget
);
1761 DeleteRelatedConstraints();
1764 /* This removes any dangling pointers to this window
1765 * in other windows' constraintsInvolvedIn lists. */
1766 UnsetConstraints(m_constraints
);
1767 delete m_constraints
;
1768 m_constraints
= (wxLayoutConstraints
*) NULL
;
1773 delete m_windowSizer
;
1774 m_windowSizer
= (wxSizer
*) NULL
;
1776 /* If this is a child of a sizer, remove self from parent */
1777 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1779 /* Just in case the window has been Closed, but
1780 * we're then deleting immediately: don't leave
1781 * dangling pointers. */
1782 wxPendingDelete
.DeleteObject(this);
1784 /* Just in case we've loaded a top-level window via
1785 * wxWindow::LoadNativeDialog but we weren't a dialog
1787 wxTopLevelWindows
.DeleteObject(this);
1789 if (m_windowValidator
) delete m_windowValidator
;
1791 if (m_clientObject
) delete m_clientObject
;
1794 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1795 const wxPoint
&pos
, const wxSize
&size
,
1796 long style
, const wxString
&name
)
1798 wxASSERT_MSG( (!m_needParent
) || (parent
), _T("Need complete parent.") );
1800 m_widget
= (GtkWidget
*) NULL
;
1801 m_wxwindow
= (GtkWidget
*) NULL
;
1804 m_children
.DeleteContents( FALSE
);
1807 if (m_width
== -1) m_width
= 20;
1809 if (m_height
== -1) m_height
= 20;
1814 if (!m_needParent
) /* some reasonable defaults */
1818 m_x
= (gdk_screen_width () - m_width
) / 2;
1819 if (m_x
< 10) m_x
= 10;
1823 m_y
= (gdk_screen_height () - m_height
) / 2;
1824 if (m_y
< 10) m_y
= 10;
1835 m_eventHandler
= this;
1837 m_windowId
= id
== -1 ? wxNewId() : id
;
1841 m_cursor
= *wxSTANDARD_CURSOR
;
1842 m_font
= *wxSWISS_FONT
;
1843 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1844 m_foregroundColour
= *wxBLACK
;
1845 m_windowStyle
= style
;
1846 m_windowName
= name
;
1848 m_constraints
= (wxLayoutConstraints
*) NULL
;
1849 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1850 m_windowSizer
= (wxSizer
*) NULL
;
1851 m_sizerParent
= (wxWindow
*) NULL
;
1852 m_autoLayout
= FALSE
;
1854 m_hasScrolling
= FALSE
;
1855 m_isScrolling
= FALSE
;
1856 m_hAdjust
= (GtkAdjustment
*) NULL
;
1857 m_vAdjust
= (GtkAdjustment
*) NULL
;
1858 m_oldHorizontalPos
= 0.0;
1859 m_oldVerticalPos
= 0.0;
1864 #if wxUSE_DRAG_AND_DROP
1865 m_dropTarget
= (wxDropTarget
*) NULL
;
1868 m_windowValidator
= (wxValidator
*) NULL
;
1869 m_scrollGC
= (GdkGC
*) NULL
;
1870 m_widgetStyle
= (GtkStyle
*) NULL
;
1872 m_clientObject
= (wxClientData
*)NULL
;
1873 m_clientData
= NULL
;
1875 m_isStaticBox
= FALSE
;
1878 m_toolTip
= (wxToolTip
*) NULL
;
1879 #endif // wxUSE_TOOLTIPS
1882 void wxWindow::PostCreation()
1884 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1888 /* these get reported to wxWindows -> wxPaintEvent */
1889 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1890 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1892 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1893 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1895 #if (GTK_MINOR_VERSION > 0)
1896 /* these are called when the "sunken" or "raised" borders are drawn */
1897 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1898 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1900 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1901 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1905 GtkWidget
*connect_widget
= GetConnectWidget();
1907 ConnectWidget( connect_widget
);
1909 /* we cannot set colours, fonts and cursors before the widget has
1910 been realized, so we do this directly after realization */
1911 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1912 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1917 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1919 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1920 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1922 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1923 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1925 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1926 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1928 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1929 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1931 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1932 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1934 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1935 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1937 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1938 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1940 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1941 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1943 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1944 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1947 bool wxWindow::HasVMT()
1952 bool wxWindow::Close( bool force
)
1954 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1956 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1957 event
.SetEventObject(this);
1958 event
.SetCanVeto(!force
);
1960 /* return FALSE if window wasn't closed because the application vetoed the
1962 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1965 bool wxWindow::Destroy()
1967 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1974 bool wxWindow::DestroyChildren()
1977 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1980 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1983 if (m_children
.Member(child
)) delete node
;
1989 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1991 // are we to set fonts here ?
1994 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1996 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1997 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1999 if (m_resizing
) return; /* I don't like recursions */
2002 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook page */
2004 /* don't set the size for children of wxNotebook, just take the values. */
2012 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
2014 if (x
!= -1) m_x
= x
;
2015 if (y
!= -1) m_y
= y
;
2016 if (width
!= -1) m_width
= width
;
2017 if (height
!= -1) m_height
= height
;
2027 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2029 if (width
== -1) m_width
= 80;
2032 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2034 if (height
== -1) m_height
= 26;
2037 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2038 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2039 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2040 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2044 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
2046 /* the default button has a border around it */
2050 /* this is the result of hours of debugging: the following code
2051 means that if we have a m_wxwindow and we set the size of
2052 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
2053 automatically propagate its size down to its m_wxwindow,
2054 which is its client area. therefore, we have to tell the
2055 client area directly that it has to resize itself.
2056 this will lead to that m_widget (GtkScrolledWindow) will
2057 calculate how much size it needs for scrollbars etc and
2058 it will then call XXX_size_allocate of its child, which
2059 is m_wxwindow. m_wxwindow in turn will do the same with its
2060 children and so on. problems can arise if this happens
2061 before all the children have been realized as some widgets
2062 stupidy need to be realized during XXX_size_allocate (e.g.
2063 GtkNotebook) and they will segv if called otherwise. this
2064 emergency is tested in gtk_myfixed_size_allocate. Normally
2065 this shouldn't be needed and only gtk_widget_queue_resize()
2066 should be enough to provoke a resize at the next appropriate
2067 moment, but this seems to fail, e.g. when a wxNotebook contains
2068 a wxSplitterWindow: the splitter window's children won't
2069 show up properly resized then. */
2071 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
2076 m_height
+2*border
);
2082 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2083 event
.SetEventObject( this );
2084 GetEventHandler()->ProcessEvent( event
);
2089 void wxWindow::OnInternalIdle()
2094 void wxWindow::GetSize( int *width
, int *height
) const
2096 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2098 if (width
) (*width
) = m_width
;
2099 if (height
) (*height
) = m_height
;
2102 void wxWindow::DoSetClientSize( int width
, int height
)
2104 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2108 SetSize( width
, height
);
2115 if (!m_hasScrolling
)
2117 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2119 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2120 (m_windowStyle
& wxSUNKEN_BORDER
))
2122 dw
+= 2 * window_class
->xthickness
;
2123 dh
+= 2 * window_class
->ythickness
;
2128 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2129 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2131 #if (GTK_MINOR_VERSION == 0)
2132 GtkWidget
*viewport
= scroll_window
->viewport
;
2133 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2135 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2136 (m_windowStyle
& wxSUNKEN_BORDER
))
2138 dw
+= 2 * viewport_class
->xthickness
;
2139 dh
+= 2 * viewport_class
->ythickness
;
2144 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2145 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2147 we use this instead: range.slider_width = 11 + 2*2pts edge
2150 if (scroll_window
->vscrollbar_visible
)
2152 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2153 dw
+= scroll_class
->scrollbar_spacing
;
2156 if (scroll_window
->hscrollbar_visible
)
2158 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2159 dw
+= scroll_class
->scrollbar_spacing
;
2163 SetSize( width
+dw
, height
+dh
);
2167 void wxWindow::GetClientSize( int *width
, int *height
) const
2169 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2173 if (width
) (*width
) = m_width
;
2174 if (height
) (*height
) = m_height
;
2181 if (!m_hasScrolling
)
2183 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2185 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2186 (m_windowStyle
& wxSUNKEN_BORDER
))
2188 dw
+= 2 * window_class
->xthickness
;
2189 dh
+= 2 * window_class
->ythickness
;
2194 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2195 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2197 #if (GTK_MINOR_VERSION == 0)
2198 GtkWidget
*viewport
= scroll_window
->viewport
;
2199 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2201 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2202 (m_windowStyle
& wxSUNKEN_BORDER
))
2204 dw
+= 2 * viewport_class
->xthickness
;
2205 dh
+= 2 * viewport_class
->ythickness
;
2209 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2210 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2212 we use this instead: range.slider_width = 11 + 2*2pts edge
2215 if (scroll_window
->vscrollbar_visible
)
2217 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2218 dw
+= scroll_class
->scrollbar_spacing
;
2221 if (scroll_window
->hscrollbar_visible
)
2223 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2224 dh
+= scroll_class
->scrollbar_spacing
;
2228 if (width
) (*width
) = m_width
- dw
;
2229 if (height
) (*height
) = m_height
- dh
;
2233 void wxWindow::GetPosition( int *x
, int *y
) const
2235 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2241 void wxWindow::ClientToScreen( int *x
, int *y
)
2243 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2245 if (!m_widget
->window
) return;
2247 GdkWindow
*source
= (GdkWindow
*) NULL
;
2249 source
= m_wxwindow
->window
;
2251 source
= m_widget
->window
;
2255 gdk_window_get_origin( source
, &org_x
, &org_y
);
2259 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2261 org_x
+= m_widget
->allocation
.x
;
2262 org_y
+= m_widget
->allocation
.y
;
2270 void wxWindow::ScreenToClient( int *x
, int *y
)
2272 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2274 if (!m_widget
->window
) return;
2276 GdkWindow
*source
= (GdkWindow
*) NULL
;
2278 source
= m_wxwindow
->window
;
2280 source
= m_widget
->window
;
2284 gdk_window_get_origin( source
, &org_x
, &org_y
);
2288 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2290 org_x
+= m_widget
->allocation
.x
;
2291 org_y
+= m_widget
->allocation
.y
;
2299 void wxWindow::Centre( int direction
)
2301 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2310 m_parent
->GetSize( &p_w
, &p_h
);
2311 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2312 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2316 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2317 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2323 void wxWindow::Fit()
2325 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2329 wxNode
*node
= m_children
.First();
2332 wxWindow
*win
= (wxWindow
*)node
->Data();
2334 win
->GetPosition(&wx
, &wy
);
2335 win
->GetSize(&ww
, &wh
);
2336 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2337 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2339 node
= node
->Next();
2342 SetClientSize(maxX
+ 7, maxY
+ 14);
2345 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2347 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2355 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2357 /* this is commented because it also is commented
2358 in wxMSW. before I get even more questions about
2360 // if (GetAutoLayout()) Layout();
2363 bool wxWindow::Show( bool show
)
2365 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2367 if (show
== m_isShown
) return TRUE
;
2370 gtk_widget_show( m_widget
);
2372 gtk_widget_hide( m_widget
);
2379 void wxWindow::Enable( bool enable
)
2381 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2383 m_isEnabled
= enable
;
2385 gtk_widget_set_sensitive( m_widget
, enable
);
2386 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2389 int wxWindow::GetCharHeight() const
2391 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2393 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2395 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2397 return font
->ascent
+ font
->descent
;
2400 int wxWindow::GetCharWidth() const
2402 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2404 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2406 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2408 return gdk_string_width( font
, "H" );
2411 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2412 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2414 wxFont fontToUse
= m_font
;
2415 if (theFont
) fontToUse
= *theFont
;
2417 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2419 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2420 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2421 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2422 if (descent
) (*descent
) = font
->descent
;
2423 if (externalLeading
) (*externalLeading
) = 0; // ??
2426 void wxWindow::MakeModal( bool modal
)
2430 // Disable all other windows
2431 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2433 wxNode
*node
= wxTopLevelWindows
.First();
2436 wxWindow
*win
= (wxWindow
*)node
->Data();
2437 if (win
!= this) win
->Enable(!modal
);
2439 node
= node
->Next();
2444 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2446 event
.SetEventType( wxEVT_CHAR
);
2448 if (!GetEventHandler()->ProcessEvent( event
))
2454 void wxWindow::SetFocus()
2456 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2458 GtkWidget
*connect_widget
= GetConnectWidget();
2461 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2463 gtk_widget_grab_focus (connect_widget
);
2465 else if (GTK_IS_CONTAINER(connect_widget
))
2467 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2475 wxWindow
*wxWindow::FindFocus()
2477 return g_focusWindow
;
2480 bool wxWindow::AcceptsFocus() const
2482 return IsEnabled() && IsShown() && m_acceptsFocus
;
2485 void wxWindow::AddChild( wxWindow
*child
)
2487 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2488 wxCHECK_RET( (child
!= NULL
), _T("invalid child") );
2490 m_children
.Append( child
);
2493 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2495 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2497 wxWindow
*oldParent
= GetParent();
2499 if (oldParent
) oldParent
->RemoveChild( this );
2501 gtk_widget_unparent( m_widget
);
2505 newParent
->AddChild( this );
2506 (newParent
->m_insertCallback
)( newParent
, this );
2512 void wxWindow::RemoveChild( wxWindow
*child
)
2514 m_children
.DeleteObject( child
);
2515 child
->m_parent
= (wxWindow
*) NULL
;
2518 void wxWindow::SetReturnCode( int retCode
)
2520 m_retCode
= retCode
;
2523 int wxWindow::GetReturnCode()
2528 void wxWindow::Raise()
2530 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2532 if (!m_widget
->window
) return;
2534 if (m_widget
) gdk_window_raise( m_widget
->window
);
2537 void wxWindow::Lower()
2539 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2541 if (!m_widget
->window
) return;
2543 if (m_widget
) gdk_window_lower( m_widget
->window
);
2546 wxEvtHandler
*wxWindow::GetEventHandler() const
2548 return m_eventHandler
;
2551 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2553 m_eventHandler
= handler
;
2556 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2558 handler
->SetNextHandler(GetEventHandler());
2559 SetEventHandler(handler
);
2562 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2564 if (GetEventHandler())
2566 wxEvtHandler
*handlerA
= GetEventHandler();
2567 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2568 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2569 SetEventHandler(handlerB
);
2573 return (wxEvtHandler
*) NULL
;
2579 return (wxEvtHandler
*) NULL
;
2582 wxValidator
*wxWindow::GetValidator()
2584 return m_windowValidator
;
2587 void wxWindow::SetValidator( const wxValidator
& validator
)
2589 if (m_windowValidator
) delete m_windowValidator
;
2590 m_windowValidator
= (wxValidator
*)validator
.Clone();
2591 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2594 void wxWindow::SetClientObject( wxClientData
*data
)
2596 if (m_clientObject
) delete m_clientObject
;
2597 m_clientObject
= data
;
2600 wxClientData
*wxWindow::GetClientObject()
2602 return m_clientObject
;
2605 void wxWindow::SetClientData( void *data
)
2607 m_clientData
= data
;
2610 void *wxWindow::GetClientData()
2612 return m_clientData
;
2615 bool wxWindow::IsBeingDeleted()
2620 void wxWindow::SetId( wxWindowID id
)
2625 wxWindowID
wxWindow::GetId() const
2630 void wxWindow::SetCursor( const wxCursor
&cursor
)
2632 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2636 if (cursor
== m_cursor
) return;
2641 m_cursor
= *wxSTANDARD_CURSOR
;
2644 if (!m_widget
->window
) return;
2646 gdk_window_set_cursor( m_widget
->window
, m_cursor
.GetCursor() );
2648 if ((m_wxwindow
) && (m_wxwindow
->window
))
2649 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
.GetCursor() );
2652 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2657 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2659 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2661 if (!m_widget
->window
) return;
2663 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2667 gdk_window_clear_area( m_wxwindow
->window
,
2669 rect
->width
, rect
->height
);
2673 gdk_window_clear( m_wxwindow
->window
);
2680 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2682 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2686 GdkRectangle gdk_rect
;
2687 gdk_rect
.x
= rect
->x
;
2688 gdk_rect
.y
= rect
->y
;
2689 gdk_rect
.width
= rect
->width
;
2690 gdk_rect
.height
= rect
->height
;
2693 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2695 gtk_widget_draw( m_widget
, &gdk_rect
);
2699 wxRegion
wxWindow::GetUpdateRegion() const
2701 return m_updateRegion
;
2704 bool wxWindow::IsExposed( int x
, int y
) const
2706 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2709 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2711 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2714 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2716 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2719 bool wxWindow::IsExposed( const wxRect
& rect
) const
2721 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2724 void wxWindow::Clear()
2726 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2728 if (!m_widget
->window
) return;
2730 if (m_wxwindow
&& m_wxwindow
->window
)
2732 gdk_window_clear( m_wxwindow
->window
);
2737 void wxWindow::SetToolTip( const wxString
&tip
)
2741 m_toolTip
->SetTip( tip
);
2745 SetToolTip( new wxToolTip( tip
) );
2748 // setting empty tooltip text does not remove the tooltip any more for
2749 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2752 void wxWindow::SetToolTip( wxToolTip
*tip
)
2756 m_toolTip
->SetTip( (char*) NULL
);
2763 m_toolTip
->Apply( this );
2766 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2768 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2770 #endif // wxUSE_TOOLTIPS
2772 wxColour
wxWindow::GetBackgroundColour() const
2774 return m_backgroundColour
;
2777 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2779 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2781 if (m_backgroundColour
== colour
) return;
2783 m_backgroundColour
= colour
;
2784 if (!m_backgroundColour
.Ok()) return;
2786 GtkWidget
*connect_widget
= GetConnectWidget();
2787 if (!connect_widget
->window
) return;
2789 if (m_wxwindow
&& m_wxwindow
->window
)
2791 /* wxMSW doesn't clear the window here. I don't do that
2792 either to provide compatibility. call Clear() to do
2795 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2796 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2799 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2801 if (sysbg
.Red() == colour
.Red() &&
2802 sysbg
.Green() == colour
.Green() &&
2803 sysbg
.Blue() == colour
.Blue())
2805 m_backgroundColour
= wxNullColour
;
2807 m_backgroundColour
= sysbg
;
2815 wxColour
wxWindow::GetForegroundColour() const
2817 return m_foregroundColour
;
2820 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2822 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2824 if (m_foregroundColour
== colour
) return;
2826 m_foregroundColour
= colour
;
2827 if (!m_foregroundColour
.Ok()) return;
2829 if (!m_widget
->window
) return;
2831 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2832 if (sysbg
.Red() == colour
.Red() &&
2833 sysbg
.Green() == colour
.Green() &&
2834 sysbg
.Blue() == colour
.Blue())
2836 m_backgroundColour
= wxNullColour
;
2838 m_backgroundColour
= sysbg
;
2846 GtkStyle
*wxWindow::GetWidgetStyle()
2848 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2852 gtk_widget_get_style( m_widget
) );
2854 return m_widgetStyle
;
2857 void wxWindow::SetWidgetStyle()
2859 GtkStyle
*style
= GetWidgetStyle();
2861 gdk_font_unref( style
->font
);
2862 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2864 if (m_foregroundColour
.Ok())
2866 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2867 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2868 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2869 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2872 if (m_backgroundColour
.Ok())
2874 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2875 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2876 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2877 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2878 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2879 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2880 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2881 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2882 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2886 void wxWindow::ApplyWidgetStyle()
2890 bool wxWindow::Validate()
2892 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2894 wxNode
*node
= m_children
.First();
2897 wxWindow
*child
= (wxWindow
*)node
->Data();
2898 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2902 node
= node
->Next();
2907 bool wxWindow::TransferDataToWindow()
2909 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2911 wxNode
*node
= m_children
.First();
2914 wxWindow
*child
= (wxWindow
*)node
->Data();
2915 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2916 !child
->GetValidator()->TransferToWindow() )
2918 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2921 node
= node
->Next();
2926 bool wxWindow::TransferDataFromWindow()
2928 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2930 wxNode
*node
= m_children
.First();
2933 wxWindow
*child
= (wxWindow
*)node
->Data();
2934 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2938 node
= node
->Next();
2943 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2945 m_acceleratorTable
= accel
;
2948 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2950 TransferDataToWindow();
2953 void wxWindow::InitDialog()
2955 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2957 wxInitDialogEvent
event(GetId());
2958 event
.SetEventObject( this );
2959 GetEventHandler()->ProcessEvent(event
);
2962 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2964 menu
->SetInvokingWindow( win
);
2965 wxNode
*node
= menu
->GetItems().First();
2968 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2969 if (menuitem
->IsSubMenu())
2971 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2973 node
= node
->Next();
2977 static gint gs_pop_x
= 0;
2978 static gint gs_pop_y
= 0;
2980 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2982 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2987 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2989 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2991 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2993 SetInvokingWindow( menu
, this );
3001 GTK_MENU(menu
->m_menu
),
3002 (GtkWidget
*) NULL
, // parent menu shell
3003 (GtkWidget
*) NULL
, // parent menu item
3004 (GtkMenuPositionFunc
) pop_pos_callback
,
3005 (gpointer
) this, // client data
3006 0, // button used to activate it
3007 0 //gs_timeLastClick // the time of activation
3012 #if wxUSE_DRAG_AND_DROP
3014 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
3016 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3018 GtkWidget
*dnd_widget
= GetConnectWidget();
3020 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
3022 if (m_dropTarget
) delete m_dropTarget
;
3023 m_dropTarget
= dropTarget
;
3025 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
3028 wxDropTarget
*wxWindow::GetDropTarget() const
3030 return m_dropTarget
;
3035 GtkWidget
* wxWindow::GetConnectWidget()
3037 GtkWidget
*connect_widget
= m_widget
;
3038 if (m_wxwindow
) connect_widget
= m_wxwindow
;
3040 return connect_widget
;
3043 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
3045 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
3046 return (window
== m_widget
->window
);
3049 void wxWindow::SetFont( const wxFont
&font
)
3051 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3053 if (m_font
== font
) return;
3055 if (((wxFont
*)&font
)->Ok())
3058 m_font
= *wxSWISS_FONT
;
3060 if (!m_widget
->window
) return;
3062 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
3063 if (sysbg
.Red() == m_backgroundColour
.Red() &&
3064 sysbg
.Green() == m_backgroundColour
.Green() &&
3065 sysbg
.Blue() == m_backgroundColour
.Blue())
3067 m_backgroundColour
= wxNullColour
;
3069 m_backgroundColour
= sysbg
;
3077 void wxWindow::SetWindowStyleFlag( long flag
)
3079 m_windowStyle
= flag
;
3082 long wxWindow::GetWindowStyleFlag() const
3084 return m_windowStyle
;
3087 void wxWindow::CaptureMouse()
3089 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3091 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
3093 if (!m_widget
->window
) return;
3095 GtkWidget
*connect_widget
= GetConnectWidget();
3096 gtk_grab_add( connect_widget
);
3097 gdk_pointer_grab( connect_widget
->window
, FALSE
,
3099 (GDK_BUTTON_PRESS_MASK
|
3100 GDK_BUTTON_RELEASE_MASK
|
3101 GDK_POINTER_MOTION_MASK
),
3108 void wxWindow::ReleaseMouse()
3110 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3112 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
3114 if (!m_widget
->window
) return;
3116 GtkWidget
*connect_widget
= GetConnectWidget();
3117 gtk_grab_remove( connect_widget
);
3118 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3119 g_capturing
= FALSE
;
3122 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
3126 wxString
wxWindow::GetTitle() const
3128 return (wxString
&)m_windowName
;
3131 wxString
wxWindow::GetLabel() const
3136 void wxWindow::SetName( const wxString
&name
)
3138 m_windowName
= name
;
3141 wxString
wxWindow::GetName() const
3143 return (wxString
&)m_windowName
;
3146 bool wxWindow::IsShown() const
3151 bool wxWindow::IsRetained()
3156 wxWindow
*wxWindow::FindWindow( long id
)
3158 if (id
== m_windowId
) return this;
3159 wxNode
*node
= m_children
.First();
3162 wxWindow
*child
= (wxWindow
*)node
->Data();
3163 wxWindow
*res
= child
->FindWindow( id
);
3164 if (res
) return res
;
3165 node
= node
->Next();
3167 return (wxWindow
*) NULL
;
3170 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
3172 if (name
== m_windowName
) return this;
3173 wxNode
*node
= m_children
.First();
3176 wxWindow
*child
= (wxWindow
*)node
->Data();
3177 wxWindow
*res
= child
->FindWindow( name
);
3178 if (res
) return res
;
3179 node
= node
->Next();
3181 return (wxWindow
*) NULL
;
3184 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3185 int range
, bool refresh
)
3187 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3189 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3191 m_hasScrolling
= TRUE
;
3193 if (orient
== wxHORIZONTAL
)
3195 float fpos
= (float)pos
;
3196 float frange
= (float)range
;
3197 float fthumb
= (float)thumbVisible
;
3198 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3199 if (fpos
< 0.0) fpos
= 0.0;
3201 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3202 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3204 SetScrollPos( orient
, pos
, refresh
);
3208 m_oldHorizontalPos
= fpos
;
3210 m_hAdjust
->lower
= 0.0;
3211 m_hAdjust
->upper
= frange
;
3212 m_hAdjust
->value
= fpos
;
3213 m_hAdjust
->step_increment
= 1.0;
3214 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3215 m_hAdjust
->page_size
= fthumb
;
3219 float fpos
= (float)pos
;
3220 float frange
= (float)range
;
3221 float fthumb
= (float)thumbVisible
;
3222 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3223 if (fpos
< 0.0) fpos
= 0.0;
3225 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3226 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3228 SetScrollPos( orient
, pos
, refresh
);
3232 m_oldVerticalPos
= fpos
;
3234 m_vAdjust
->lower
= 0.0;
3235 m_vAdjust
->upper
= frange
;
3236 m_vAdjust
->value
= fpos
;
3237 m_vAdjust
->step_increment
= 1.0;
3238 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3239 m_vAdjust
->page_size
= fthumb
;
3244 if (orient
== wxHORIZONTAL
)
3245 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3247 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3249 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3253 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3255 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3257 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3259 if (orient
== wxHORIZONTAL
)
3261 float fpos
= (float)pos
;
3262 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3263 if (fpos
< 0.0) fpos
= 0.0;
3264 m_oldHorizontalPos
= fpos
;
3266 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3267 m_hAdjust
->value
= fpos
;
3271 float fpos
= (float)pos
;
3272 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3273 if (fpos
< 0.0) fpos
= 0.0;
3274 m_oldVerticalPos
= fpos
;
3276 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3277 m_vAdjust
->value
= fpos
;
3282 if (m_wxwindow
->window
)
3284 if (orient
== wxHORIZONTAL
)
3285 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3287 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3292 int wxWindow::GetScrollThumb( int orient
) const
3294 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3296 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3298 if (orient
== wxHORIZONTAL
)
3299 return (int)(m_hAdjust
->page_size
+0.5);
3301 return (int)(m_vAdjust
->page_size
+0.5);
3304 int wxWindow::GetScrollPos( int orient
) const
3306 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3308 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3310 if (orient
== wxHORIZONTAL
)
3311 return (int)(m_hAdjust
->value
+0.5);
3313 return (int)(m_vAdjust
->value
+0.5);
3316 int wxWindow::GetScrollRange( int orient
) const
3318 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3320 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3322 if (orient
== wxHORIZONTAL
)
3323 return (int)(m_hAdjust
->upper
+0.5);
3325 return (int)(m_vAdjust
->upper
+0.5);
3328 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3330 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3332 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3334 wxNode
*node
= m_children
.First();
3337 wxWindow
*child
= (wxWindow
*) node
->Data();
3338 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
3339 node
= node
->Next();
3344 GetClientSize( &cw
, &ch
);
3346 int w
= cw
- abs(dx
);
3347 int h
= ch
- abs(dy
);
3348 if ((h
< 0) || (w
< 0))
3355 if (dx
< 0) s_x
= -dx
;
3356 if (dy
< 0) s_y
= -dy
;
3359 if (dx
> 0) d_x
= dx
;
3360 if (dy
> 0) d_y
= dy
;
3364 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3365 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3368 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3369 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3372 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3373 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3374 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3375 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3377 Refresh( TRUE
, &rect
);
3380 //-------------------------------------------------------------------------------------
3382 //-------------------------------------------------------------------------------------
3384 wxLayoutConstraints
*wxWindow::GetConstraints() const
3386 return m_constraints
;
3389 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3393 UnsetConstraints(m_constraints
);
3394 delete m_constraints
;
3396 m_constraints
= constraints
;
3399 // Make sure other windows know they're part of a 'meaningful relationship'
3400 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3401 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3402 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3403 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3404 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3405 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3406 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3407 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3408 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3409 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3410 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3411 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3412 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3413 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3414 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3415 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3421 void wxWindow::SetAutoLayout( bool autoLayout
)
3423 m_autoLayout
= autoLayout
;
3426 bool wxWindow::GetAutoLayout() const
3428 return m_autoLayout
;
3431 wxSizer
*wxWindow::GetSizer() const
3433 return m_windowSizer
;
3436 void wxWindow::SetSizerParent( wxWindow
*win
)
3438 m_sizerParent
= win
;
3441 wxWindow
*wxWindow::GetSizerParent() const
3443 return m_sizerParent
;
3446 // This removes any dangling pointers to this window
3447 // in other windows' constraintsInvolvedIn lists.
3448 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3452 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3453 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3454 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3455 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3456 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3457 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3458 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3459 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3460 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3461 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3462 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3463 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3464 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3465 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3466 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3467 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3471 // Back-pointer to other windows we're involved with, so if we delete
3472 // this window, we must delete any constraints we're involved with.
3473 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3475 if (!m_constraintsInvolvedIn
)
3476 m_constraintsInvolvedIn
= new wxList
;
3477 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3478 m_constraintsInvolvedIn
->Append(otherWin
);
3481 // REMOVE back-pointer to other windows we're involved with.
3482 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3484 if (m_constraintsInvolvedIn
)
3485 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3488 // Reset any constraints that mention this window
3489 void wxWindow::DeleteRelatedConstraints()
3491 if (m_constraintsInvolvedIn
)
3493 wxNode
*node
= m_constraintsInvolvedIn
->First();
3496 wxWindow
*win
= (wxWindow
*)node
->Data();
3497 wxNode
*next
= node
->Next();
3498 wxLayoutConstraints
*constr
= win
->GetConstraints();
3500 // Reset any constraints involving this window
3503 constr
->left
.ResetIfWin((wxWindow
*)this);
3504 constr
->top
.ResetIfWin((wxWindow
*)this);
3505 constr
->right
.ResetIfWin((wxWindow
*)this);
3506 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3507 constr
->width
.ResetIfWin((wxWindow
*)this);
3508 constr
->height
.ResetIfWin((wxWindow
*)this);
3509 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3510 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3515 delete m_constraintsInvolvedIn
;
3516 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3520 void wxWindow::SetSizer(wxSizer
*sizer
)
3522 m_windowSizer
= sizer
;
3524 sizer
->SetSizerParent((wxWindow
*)this);
3531 bool wxWindow::Layout()
3533 if (GetConstraints())
3536 GetClientSize(&w
, &h
);
3537 GetConstraints()->width
.SetValue(w
);
3538 GetConstraints()->height
.SetValue(h
);
3541 // If top level (one sizer), evaluate the sizer's constraints.
3545 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3546 GetSizer()->LayoutPhase1(&noChanges
);
3547 GetSizer()->LayoutPhase2(&noChanges
);
3548 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3554 // Otherwise, evaluate child constraints
3555 ResetConstraints(); // Mark all constraints as unevaluated
3556 DoPhase(1); // Just one phase need if no sizers involved
3558 SetConstraintSizes(); // Recursively set the real window sizes
3564 // Do a phase of evaluating constraints:
3565 // the default behaviour. wxSizers may do a similar
3566 // thing, but also impose their own 'constraints'
3567 // and order the evaluation differently.
3568 bool wxWindow::LayoutPhase1(int *noChanges
)
3570 wxLayoutConstraints
*constr
= GetConstraints();
3573 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3579 bool wxWindow::LayoutPhase2(int *noChanges
)
3589 // Do a phase of evaluating child constraints
3590 bool wxWindow::DoPhase(int phase
)
3592 int noIterations
= 0;
3593 int maxIterations
= 500;
3597 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3601 wxNode
*node
= m_children
.First();
3604 wxWindow
*child
= (wxWindow
*)node
->Data();
3605 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3607 wxLayoutConstraints
*constr
= child
->GetConstraints();
3610 if (succeeded
.Member(child
))
3615 int tempNoChanges
= 0;
3616 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3617 noChanges
+= tempNoChanges
;
3620 succeeded
.Append(child
);
3625 node
= node
->Next();
3632 void wxWindow::ResetConstraints()
3634 wxLayoutConstraints
*constr
= GetConstraints();
3637 constr
->left
.SetDone(FALSE
);
3638 constr
->top
.SetDone(FALSE
);
3639 constr
->right
.SetDone(FALSE
);
3640 constr
->bottom
.SetDone(FALSE
);
3641 constr
->width
.SetDone(FALSE
);
3642 constr
->height
.SetDone(FALSE
);
3643 constr
->centreX
.SetDone(FALSE
);
3644 constr
->centreY
.SetDone(FALSE
);
3646 wxNode
*node
= m_children
.First();
3649 wxWindow
*win
= (wxWindow
*)node
->Data();
3650 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3651 win
->ResetConstraints();
3652 node
= node
->Next();
3656 // Need to distinguish between setting the 'fake' size for
3657 // windows and sizers, and setting the real values.
3658 void wxWindow::SetConstraintSizes(bool recurse
)
3660 wxLayoutConstraints
*constr
= GetConstraints();
3661 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3662 constr
->width
.GetDone() && constr
->height
.GetDone())
3664 int x
= constr
->left
.GetValue();
3665 int y
= constr
->top
.GetValue();
3666 int w
= constr
->width
.GetValue();
3667 int h
= constr
->height
.GetValue();
3669 // If we don't want to resize this window, just move it...
3670 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3671 (constr
->height
.GetRelationship() != wxAsIs
))
3673 // Calls Layout() recursively. AAAGH. How can we stop that.
3674 // Simply take Layout() out of non-top level OnSizes.
3675 SizerSetSize(x
, y
, w
, h
);
3684 wxChar
*windowClass
= this->GetClassInfo()->GetClassName();
3687 if (GetName() == _T(""))
3688 winName
= _T("unnamed");
3690 winName
= GetName();
3691 wxLogDebug( _T("Constraint(s) not satisfied for window of type %s, name %s:\n"),
3692 (const wxChar
*)windowClass
,
3693 (const wxChar
*)winName
);
3694 if (!constr
->left
.GetDone()) wxLogDebug( _T(" unsatisfied 'left' constraint.\n") );
3695 if (!constr
->right
.GetDone()) wxLogDebug( _T(" unsatisfied 'right' constraint.\n") );
3696 if (!constr
->width
.GetDone()) wxLogDebug( _T(" unsatisfied 'width' constraint.\n") );
3697 if (!constr
->height
.GetDone()) wxLogDebug( _T(" unsatisfied 'height' constraint.\n") );
3698 wxLogDebug( _T("Please check constraints: try adding AsIs() constraints.\n") );
3703 wxNode
*node
= m_children
.First();
3706 wxWindow
*win
= (wxWindow
*)node
->Data();
3707 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3708 win
->SetConstraintSizes();
3709 node
= node
->Next();
3714 // This assumes that all sizers are 'on' the same
3715 // window, i.e. the parent of this window.
3716 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3718 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3719 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3723 m_sizerParent
->GetPosition(&xp
, &yp
);
3724 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3729 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3733 TransformSizerToActual(&xx
, &yy
);
3734 SetSize(xx
, yy
, w
, h
);
3737 void wxWindow::SizerMove(int x
, int y
)
3741 TransformSizerToActual(&xx
, &yy
);
3745 // Only set the size/position of the constraint (if any)
3746 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3748 wxLayoutConstraints
*constr
= GetConstraints();
3753 constr
->left
.SetValue(x
);
3754 constr
->left
.SetDone(TRUE
);
3758 constr
->top
.SetValue(y
);
3759 constr
->top
.SetDone(TRUE
);
3763 constr
->width
.SetValue(w
);
3764 constr
->width
.SetDone(TRUE
);
3768 constr
->height
.SetValue(h
);
3769 constr
->height
.SetDone(TRUE
);
3774 void wxWindow::MoveConstraint(int x
, int y
)
3776 wxLayoutConstraints
*constr
= GetConstraints();
3781 constr
->left
.SetValue(x
);
3782 constr
->left
.SetDone(TRUE
);
3786 constr
->top
.SetValue(y
);
3787 constr
->top
.SetDone(TRUE
);
3792 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3794 wxLayoutConstraints
*constr
= GetConstraints();
3797 *w
= constr
->width
.GetValue();
3798 *h
= constr
->height
.GetValue();
3804 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3806 wxLayoutConstraints
*constr
= GetConstraints();
3809 *w
= constr
->width
.GetValue();
3810 *h
= constr
->height
.GetValue();
3813 GetClientSize(w
, h
);
3816 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3818 wxLayoutConstraints
*constr
= GetConstraints();
3821 *x
= constr
->left
.GetValue();
3822 *y
= constr
->top
.GetValue();