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 wxPrintf( _T("FOCUS NOW AT: ") );
136 wxPrintf( _T("\n") );
141 void debug_focus_in( GtkWidget
* widget
, const wxChar
* name
, const wxChar
*window
)
147 wxChar
*s
= new wxChar
[tmp
.Length()+1];
151 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
152 GTK_SIGNAL_FUNC(gtk_debug_focus_in_callback
), (gpointer
)s
);
157 //-----------------------------------------------------------------------------
159 //-----------------------------------------------------------------------------
161 extern wxList wxPendingDelete
;
162 extern bool g_blockEventsOnDrag
;
163 extern bool g_blockEventsOnScroll
;
164 extern bool g_isIdle
;
165 static bool g_capturing
= FALSE
;
166 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
168 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
169 the last click here */
170 static guint32 gs_timeLastClick
= 0;
172 //-----------------------------------------------------------------------------
174 //-----------------------------------------------------------------------------
176 extern void wxapp_install_idle_handler();
177 extern bool g_isIdle
;
179 #if (GTK_MINOR_VERSION > 0)
181 //-----------------------------------------------------------------------------
182 // local code (see below)
183 //-----------------------------------------------------------------------------
185 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
187 if (!win
->HasVMT()) return;
192 if (win
->m_hasScrolling
)
194 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
195 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
198 GtkWidget *hscrollbar = scroll_window->hscrollbar;
199 GtkWidget *vscrollbar = scroll_window->vscrollbar;
201 we use this instead: range.slider_width = 11 + 2*2pts edge
204 if (scroll_window
->vscrollbar_visible
)
206 dw
+= 15; /* dw += vscrollbar->allocation.width; */
207 dw
+= scroll_class
->scrollbar_spacing
;
210 if (scroll_window
->hscrollbar_visible
)
212 dh
+= 15; /* dh += hscrollbar->allocation.height; */
213 dw
+= scroll_class
->scrollbar_spacing
;
219 if (GTK_WIDGET_NO_WINDOW (widget
))
221 dx
+= widget
->allocation
.x
;
222 dy
+= widget
->allocation
.y
;
225 if (win
->m_windowStyle
& wxRAISED_BORDER
)
227 gtk_draw_shadow( widget
->style
,
232 win
->m_width
-dw
, win
->m_height
-dh
);
236 if (win
->m_windowStyle
& wxSUNKEN_BORDER
)
238 gtk_draw_shadow( widget
->style
,
243 win
->m_width
-dw
, win
->m_height
-dh
);
248 //-----------------------------------------------------------------------------
249 // "expose_event" of m_widget
250 //-----------------------------------------------------------------------------
252 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
254 if (gdk_event
->count
> 0) return;
255 draw_frame( widget
, win
);
258 //-----------------------------------------------------------------------------
259 // "draw" of m_wxwindow
260 //-----------------------------------------------------------------------------
262 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
264 draw_frame( widget
, win
);
269 //-----------------------------------------------------------------------------
270 // "expose_event" of m_wxwindow
271 //-----------------------------------------------------------------------------
273 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
275 if (g_isIdle
) wxapp_install_idle_handler();
277 if (!win
->HasVMT()) return;
279 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
281 gdk_event
->area
.width
,
282 gdk_event
->area
.height
);
284 if (gdk_event
->count
> 0) return;
287 printf( "OnExpose from " );
288 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
289 printf( win->GetClassInfo()->GetClassName() );
293 wxPaintEvent
event( win
->GetId() );
294 event
.SetEventObject( win
);
295 win
->GetEventHandler()->ProcessEvent( event
);
297 win
->m_updateRegion
.Clear();
300 //-----------------------------------------------------------------------------
301 // "draw" of m_wxwindow
302 //-----------------------------------------------------------------------------
304 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
306 if (g_isIdle
) wxapp_install_idle_handler();
308 if (!win
->HasVMT()) return;
310 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
312 wxPaintEvent
event( win
->GetId() );
313 event
.SetEventObject( win
);
314 win
->GetEventHandler()->ProcessEvent( event
);
316 win
->m_updateRegion
.Clear();
319 //-----------------------------------------------------------------------------
320 // "key_press_event" from any window
321 //-----------------------------------------------------------------------------
323 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
325 if (g_isIdle
) wxapp_install_idle_handler();
327 if (!win
->HasVMT()) return FALSE
;
328 if (g_blockEventsOnDrag
) return FALSE
;
331 wxPrintf( _T("OnKeyPress from ") );
332 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
333 wxPrintf( win->GetClassInfo()->GetClassName() );
334 wxPrintf( _T(".\n") );
338 switch (gdk_event
->keyval
)
340 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
341 case GDK_ISO_Left_Tab
:
343 case GDK_Tab
: key_code
= WXK_TAB
; break;
344 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
345 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
346 case GDK_Return
: key_code
= WXK_RETURN
; break;
347 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
348 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
349 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
350 case GDK_Delete
: key_code
= WXK_DELETE
; break;
351 case GDK_Home
: key_code
= WXK_HOME
; break;
352 case GDK_Left
: key_code
= WXK_LEFT
; break;
353 case GDK_Up
: key_code
= WXK_UP
; break;
354 case GDK_Right
: key_code
= WXK_RIGHT
; break;
355 case GDK_Down
: key_code
= WXK_DOWN
; break;
356 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
357 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
358 case GDK_Next
: key_code
= WXK_NEXT
; break;
359 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
360 case GDK_End
: key_code
= WXK_END
; break;
361 case GDK_Begin
: key_code
= WXK_HOME
; break;
362 case GDK_Select
: key_code
= WXK_SELECT
; break;
363 case GDK_Print
: key_code
= WXK_PRINT
; break;
364 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
365 case GDK_Insert
: key_code
= WXK_INSERT
; break;
366 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
367 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
368 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
369 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
370 case GDK_KP_Up
: key_code
= WXK_UP
; break;
371 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
372 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
373 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
374 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
375 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
376 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
377 case GDK_KP_End
: key_code
= WXK_END
; break;
378 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
379 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
380 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
381 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
382 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
383 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
384 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
385 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
386 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
387 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
388 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
389 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
390 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
391 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
392 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
393 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
394 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
395 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
396 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
397 case GDK_F1
: key_code
= WXK_F1
; break;
398 case GDK_F2
: key_code
= WXK_F2
; break;
399 case GDK_F3
: key_code
= WXK_F3
; break;
400 case GDK_F4
: key_code
= WXK_F4
; break;
401 case GDK_F5
: key_code
= WXK_F5
; break;
402 case GDK_F6
: key_code
= WXK_F6
; break;
403 case GDK_F7
: key_code
= WXK_F7
; break;
404 case GDK_F8
: key_code
= WXK_F8
; break;
405 case GDK_F9
: key_code
= WXK_F9
; break;
406 case GDK_F10
: key_code
= WXK_F10
; break;
407 case GDK_F11
: key_code
= WXK_F11
; break;
408 case GDK_F12
: key_code
= WXK_F12
; break;
411 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
412 key_code
= gdk_event
->keyval
;
416 if (!key_code
) return FALSE
;
418 wxKeyEvent
event( wxEVT_KEY_DOWN
);
419 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
420 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
421 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
422 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
423 event
.m_keyCode
= key_code
;
426 event
.SetEventObject( win
);
428 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
432 wxWindow
*ancestor
= win
;
435 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
438 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
439 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
442 ancestor
= ancestor
->GetParent();
446 // win is a control: tab can be propagated up
448 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
449 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
451 wxNavigationKeyEvent new_event
;
452 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
453 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
454 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
455 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
456 new_event
.SetCurrentFocus( win
);
457 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
461 (gdk_event
->keyval
== GDK_Escape
) )
463 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
464 new_event
.SetEventObject( win
);
465 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
469 Damn, I forgot why this didn't work, but it didn't work.
471 // win is a panel: up can be propagated to the panel
472 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
473 (gdk_event->keyval == GDK_Up))
475 win->m_parent->SetFocus();
479 // win is a panel: left/right can be propagated to the panel
480 if ((!ret) && (win->m_wxwindow) &&
481 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
482 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
484 wxNavigationKeyEvent new_event;
485 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
486 new_event.SetCurrentFocus( win );
487 ret = win->GetEventHandler()->ProcessEvent( new_event );
493 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
500 //-----------------------------------------------------------------------------
501 // "key_release_event" from any window
502 //-----------------------------------------------------------------------------
504 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
506 if (g_isIdle
) wxapp_install_idle_handler();
508 if (!win
->HasVMT()) return FALSE
;
509 if (g_blockEventsOnDrag
) return FALSE
;
512 printf( "OnKeyRelease from " );
513 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
514 printf( win->GetClassInfo()->GetClassName() );
519 switch (gdk_event
->keyval
)
521 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
522 case GDK_ISO_Left_Tab
:
524 case GDK_Tab
: key_code
= WXK_TAB
; break;
525 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
526 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
527 case GDK_Return
: key_code
= WXK_RETURN
; break;
528 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
529 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
530 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
531 case GDK_Delete
: key_code
= WXK_DELETE
; break;
532 case GDK_Home
: key_code
= WXK_HOME
; break;
533 case GDK_Left
: key_code
= WXK_LEFT
; break;
534 case GDK_Up
: key_code
= WXK_UP
; break;
535 case GDK_Right
: key_code
= WXK_RIGHT
; break;
536 case GDK_Down
: key_code
= WXK_DOWN
; break;
537 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
538 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
539 case GDK_Next
: key_code
= WXK_NEXT
; break;
540 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
541 case GDK_End
: key_code
= WXK_END
; break;
542 case GDK_Begin
: key_code
= WXK_HOME
; break;
543 case GDK_Select
: key_code
= WXK_SELECT
; break;
544 case GDK_Print
: key_code
= WXK_PRINT
; break;
545 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
546 case GDK_Insert
: key_code
= WXK_INSERT
; break;
547 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
548 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
549 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
550 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
551 case GDK_KP_Up
: key_code
= WXK_UP
; break;
552 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
553 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
554 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
555 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
556 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
557 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
558 case GDK_KP_End
: key_code
= WXK_END
; break;
559 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
560 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
561 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
562 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
563 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
564 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
565 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
566 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
567 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
568 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
569 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
570 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
571 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
572 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
573 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
574 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
575 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
576 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
577 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
578 case GDK_F1
: key_code
= WXK_F1
; break;
579 case GDK_F2
: key_code
= WXK_F2
; break;
580 case GDK_F3
: key_code
= WXK_F3
; break;
581 case GDK_F4
: key_code
= WXK_F4
; break;
582 case GDK_F5
: key_code
= WXK_F5
; break;
583 case GDK_F6
: key_code
= WXK_F6
; break;
584 case GDK_F7
: key_code
= WXK_F7
; break;
585 case GDK_F8
: key_code
= WXK_F8
; break;
586 case GDK_F9
: key_code
= WXK_F9
; break;
587 case GDK_F10
: key_code
= WXK_F10
; break;
588 case GDK_F11
: key_code
= WXK_F11
; break;
589 case GDK_F12
: key_code
= WXK_F12
; break;
592 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
593 key_code
= gdk_event
->keyval
;
597 if (!key_code
) return FALSE
;
599 wxKeyEvent
event( wxEVT_KEY_UP
);
600 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
601 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
602 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
603 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
604 event
.m_keyCode
= key_code
;
607 event
.SetEventObject( win
);
609 if (win
->GetEventHandler()->ProcessEvent( event
))
611 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
618 //-----------------------------------------------------------------------------
619 // "button_press_event"
620 //-----------------------------------------------------------------------------
622 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
624 if (g_isIdle
) wxapp_install_idle_handler();
627 wxPrintf( _T("1) OnButtonPress from ") );
628 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
629 wxPrintf( win->GetClassInfo()->GetClassName() );
630 wxPrintf( _T(".\n") );
633 if (!win
->HasVMT()) return FALSE
;
634 if (g_blockEventsOnDrag
) return TRUE
;
635 if (g_blockEventsOnScroll
) return TRUE
;
637 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
641 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
643 gtk_widget_grab_focus (win
->m_wxwindow
);
646 wxPrintf( _T("GrabFocus from ") );
647 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
648 wxPrintf( win->GetClassInfo()->GetClassName() );
649 wxPrintf( _T(".\n") );
656 wxPrintf( _T("No GrabFocus from ") );
657 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
658 wxPrintf( win->GetClassInfo()->GetClassName() );
659 if (GTK_WIDGET_CAN_FOCUS(win->m_wxwindow))
660 wxPrintf( _T(" because it already has") );
661 wxPrintf( _T(".\n") );
667 wxPrintf( _T("2) OnButtonPress from ") );
668 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
669 wxPrintf( win->GetClassInfo()->GetClassName() );
670 wxPrintf( _T(".\n") );
673 wxEventType event_type
= wxEVT_LEFT_DOWN
;
675 if (gdk_event
->button
== 1)
677 switch (gdk_event
->type
)
679 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
680 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
684 else if (gdk_event
->button
== 2)
686 switch (gdk_event
->type
)
688 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
689 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
693 else if (gdk_event
->button
== 3)
695 switch (gdk_event
->type
)
697 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
698 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
703 wxMouseEvent
event( event_type
);
704 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
705 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
706 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
707 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
708 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
709 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
710 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
712 event
.m_x
= (long)gdk_event
->x
;
713 event
.m_y
= (long)gdk_event
->y
;
715 // Some control don't have their own X window and thus cannot get
720 wxNode
*node
= win
->GetChildren().First();
723 wxWindow
*child
= (wxWindow
*)node
->Data();
725 if (child
->m_isStaticBox
)
727 // wxStaticBox is transparent in the box itself
730 int xx1
= child
->m_x
;
731 int yy1
= child
->m_y
;
732 int xx2
= child
->m_x
+ child
->m_width
;
733 int yy2
= child
->m_x
+ child
->m_height
;
736 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
738 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
740 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
742 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
745 event
.m_x
-= child
->m_x
;
746 event
.m_y
-= child
->m_y
;
753 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
754 (child
->m_x
<= event
.m_x
) &&
755 (child
->m_y
<= event
.m_y
) &&
756 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
757 (child
->m_y
+child
->m_height
>= event
.m_y
))
760 event
.m_x
-= child
->m_x
;
761 event
.m_y
-= child
->m_y
;
769 event
.SetEventObject( win
);
771 gs_timeLastClick
= gdk_event
->time
;
773 if (win
->GetEventHandler()->ProcessEvent( event
))
775 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
782 //-----------------------------------------------------------------------------
783 // "button_release_event"
784 //-----------------------------------------------------------------------------
786 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
788 if (g_isIdle
) wxapp_install_idle_handler();
790 if (!win
->HasVMT()) return FALSE
;
791 if (g_blockEventsOnDrag
) return FALSE
;
792 if (g_blockEventsOnScroll
) return FALSE
;
794 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
797 printf( "OnButtonRelease from " );
798 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
799 printf( win->GetClassInfo()->GetClassName() );
803 wxEventType event_type
= wxEVT_NULL
;
805 switch (gdk_event
->button
)
807 case 1: event_type
= wxEVT_LEFT_UP
; break;
808 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
809 case 3: event_type
= wxEVT_RIGHT_UP
; break;
812 wxMouseEvent
event( event_type
);
813 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
814 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
815 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
816 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
817 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
818 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
819 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
820 event
.m_x
= (long)gdk_event
->x
;
821 event
.m_y
= (long)gdk_event
->y
;
823 // Some control don't have their own X window and thus cannot get
828 wxNode
*node
= win
->GetChildren().First();
831 wxWindow
*child
= (wxWindow
*)node
->Data();
833 if (child
->m_isStaticBox
)
835 // wxStaticBox is transparent in the box itself
838 int xx1
= child
->m_x
;
839 int yy1
= child
->m_y
;
840 int xx2
= child
->m_x
+ child
->m_width
;
841 int yy2
= child
->m_x
+ child
->m_height
;
844 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
846 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
848 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
850 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
853 event
.m_x
-= child
->m_x
;
854 event
.m_y
-= child
->m_y
;
861 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
862 (child
->m_x
<= event
.m_x
) &&
863 (child
->m_y
<= event
.m_y
) &&
864 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
865 (child
->m_y
+child
->m_height
>= event
.m_y
))
868 event
.m_x
-= child
->m_x
;
869 event
.m_y
-= child
->m_y
;
877 event
.SetEventObject( win
);
879 if (win
->GetEventHandler()->ProcessEvent( event
))
881 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
888 //-----------------------------------------------------------------------------
889 // "motion_notify_event"
890 //-----------------------------------------------------------------------------
892 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
894 if (g_isIdle
) wxapp_install_idle_handler();
896 if (!win
->HasVMT()) return FALSE
;
897 if (g_blockEventsOnDrag
) return FALSE
;
898 if (g_blockEventsOnScroll
) return FALSE
;
900 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
902 if (gdk_event
->is_hint
)
906 GdkModifierType state
;
907 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
910 gdk_event
->state
= state
;
914 printf( "OnMotion from " );
915 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
916 printf( win->GetClassInfo()->GetClassName() );
920 wxMouseEvent
event( wxEVT_MOTION
);
921 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
922 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
923 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
924 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
925 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
926 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
927 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
929 event
.m_x
= (long)gdk_event
->x
;
930 event
.m_y
= (long)gdk_event
->y
;
932 // Some control don't have their own X window and thus cannot get
937 wxNode
*node
= win
->GetChildren().First();
940 wxWindow
*child
= (wxWindow
*)node
->Data();
942 if (child
->m_isStaticBox
)
944 // wxStaticBox is transparent in the box itself
947 int xx1
= child
->m_x
;
948 int yy1
= child
->m_y
;
949 int xx2
= child
->m_x
+ child
->m_width
;
950 int yy2
= child
->m_x
+ child
->m_height
;
953 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
955 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
957 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
959 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
962 event
.m_x
-= child
->m_x
;
963 event
.m_y
-= child
->m_y
;
970 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
971 (child
->m_x
<= event
.m_x
) &&
972 (child
->m_y
<= event
.m_y
) &&
973 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
974 (child
->m_y
+child
->m_height
>= event
.m_y
))
977 event
.m_x
-= child
->m_x
;
978 event
.m_y
-= child
->m_y
;
986 event
.SetEventObject( win
);
988 if (win
->GetEventHandler()->ProcessEvent( event
))
990 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
997 //-----------------------------------------------------------------------------
999 //-----------------------------------------------------------------------------
1001 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1003 if (g_isIdle
) wxapp_install_idle_handler();
1005 if (!win
->HasVMT()) return FALSE
;
1006 if (g_blockEventsOnDrag
) return FALSE
;
1008 g_focusWindow
= win
;
1010 if (win
->m_wxwindow
)
1012 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1014 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1016 printf( "SetFocus flag from " );
1017 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1018 printf( win->GetClassInfo()->GetClassName() );
1026 wxPrintf( _T("OnSetFocus from ") );
1027 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1028 wxPrintf( win->GetClassInfo()->GetClassName() );
1029 wxPrintf( _T(" ") );
1030 wxPrintf( win->GetLabel() );
1031 wxPrintf( _T(".\n") );
1034 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
1035 event
.SetEventObject( win
);
1037 if (win
->GetEventHandler()->ProcessEvent( event
))
1039 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
1046 //-----------------------------------------------------------------------------
1047 // "focus_out_event"
1048 //-----------------------------------------------------------------------------
1050 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
1052 if (g_isIdle
) wxapp_install_idle_handler();
1054 if (!win
->HasVMT()) return FALSE
;
1055 if (g_blockEventsOnDrag
) return FALSE
;
1057 if (win
->m_wxwindow
)
1059 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
1060 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
1064 wxPrintf( _T("OnKillFocus from ") );
1065 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1066 wxPrintf( win->GetClassInfo()->GetClassName() );
1067 wxPrintf( _T(" ") );
1068 wxPrintf( win->GetLabel() );
1069 wxPrintf( _T(".\n") );
1072 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
1073 event
.SetEventObject( win
);
1075 if (win
->GetEventHandler()->ProcessEvent( event
))
1077 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1084 //-----------------------------------------------------------------------------
1085 // "enter_notify_event"
1086 //-----------------------------------------------------------------------------
1088 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1090 if (g_isIdle
) wxapp_install_idle_handler();
1092 if (!win
->HasVMT()) return FALSE
;
1093 if (g_blockEventsOnDrag
) return FALSE
;
1095 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1097 if ((widget
->window
) && (win
->m_cursor
.Ok()))
1098 gdk_window_set_cursor( widget
->window
, win
->m_cursor
.GetCursor() );
1101 printf( "OnEnter from " );
1102 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1103 printf( win->GetClassInfo()->GetClassName() );
1107 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1108 event
.SetEventObject( win
);
1112 GdkModifierType state
= (GdkModifierType
)0;
1114 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1116 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1117 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1118 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1119 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1120 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1121 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1122 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1124 event
.m_x
= (long)x
;
1125 event
.m_y
= (long)y
;
1127 if (win
->GetEventHandler()->ProcessEvent( event
))
1129 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1136 //-----------------------------------------------------------------------------
1137 // "leave_notify_event"
1138 //-----------------------------------------------------------------------------
1140 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1142 if (g_isIdle
) wxapp_install_idle_handler();
1144 if (!win
->HasVMT()) return FALSE
;
1145 if (g_blockEventsOnDrag
) return FALSE
;
1147 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1150 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1153 printf( "OnLeave from " );
1154 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1155 printf( win->GetClassInfo()->GetClassName() );
1159 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1160 event
.SetEventObject( win
);
1164 GdkModifierType state
= (GdkModifierType
)0;
1166 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1168 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1169 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1170 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1171 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1172 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1173 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1174 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1176 event
.m_x
= (long)x
;
1177 event
.m_y
= (long)y
;
1179 if (win
->GetEventHandler()->ProcessEvent( event
))
1181 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1188 //-----------------------------------------------------------------------------
1189 // "value_changed" from m_vAdjust
1190 //-----------------------------------------------------------------------------
1192 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1194 if (g_isIdle
) wxapp_install_idle_handler();
1196 if (g_blockEventsOnDrag
) return;
1199 printf( "OnVScroll from " );
1200 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1201 printf( win->GetClassInfo()->GetClassName() );
1205 if (!win
->HasVMT()) return;
1207 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1208 if (fabs(diff
) < 0.2) return;
1209 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1211 wxEventType command
= wxEVT_NULL
;
1213 float line_step
= win
->m_vAdjust
->step_increment
;
1214 float page_step
= win
->m_vAdjust
->page_increment
;
1216 if (win
->m_isScrolling
)
1218 command
= wxEVT_SCROLL_THUMBTRACK
;
1222 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1223 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1224 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1225 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1226 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1227 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1228 else command
= wxEVT_SCROLL_THUMBTRACK
;
1231 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1233 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1234 event
.SetEventObject( win
);
1235 win
->GetEventHandler()->ProcessEvent( event
);
1238 //-----------------------------------------------------------------------------
1239 // "value_changed" from m_hAdjust
1240 //-----------------------------------------------------------------------------
1242 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1244 if (g_isIdle
) wxapp_install_idle_handler();
1246 if (g_blockEventsOnDrag
) return;
1249 printf( "OnHScroll from " );
1250 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1251 printf( win->GetClassInfo()->GetClassName() );
1255 if (!win
->HasVMT()) return;
1257 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1258 if (fabs(diff
) < 0.2) return;
1259 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1261 wxEventType command
= wxEVT_NULL
;
1263 float line_step
= win
->m_hAdjust
->step_increment
;
1264 float page_step
= win
->m_hAdjust
->page_increment
;
1266 if (win
->m_isScrolling
)
1268 command
= wxEVT_SCROLL_THUMBTRACK
;
1272 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1273 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1274 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1275 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1276 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1277 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1278 else command
= wxEVT_SCROLL_THUMBTRACK
;
1281 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1283 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1284 event
.SetEventObject( win
);
1285 win
->GetEventHandler()->ProcessEvent( event
);
1288 //-----------------------------------------------------------------------------
1289 // "changed" from m_vAdjust
1290 //-----------------------------------------------------------------------------
1292 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1294 if (g_isIdle
) wxapp_install_idle_handler();
1296 if (g_blockEventsOnDrag
) return;
1299 printf( "OnVScroll change from " );
1300 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1301 printf( win->GetClassInfo()->GetClassName() );
1305 if (!win
->HasVMT()) return;
1307 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1308 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1310 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1311 event
.SetEventObject( win
);
1312 win
->GetEventHandler()->ProcessEvent( event
);
1315 //-----------------------------------------------------------------------------
1316 // "changed" from m_hAdjust
1317 //-----------------------------------------------------------------------------
1319 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1321 if (g_isIdle
) wxapp_install_idle_handler();
1323 if (g_blockEventsOnDrag
) return;
1326 printf( "OnHScroll change from " );
1327 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1328 printf( win->GetClassInfo()->GetClassName() );
1332 if (!win
->HasVMT()) return;
1334 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1335 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1337 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1338 event
.SetEventObject( win
);
1339 win
->GetEventHandler()->ProcessEvent( event
);
1342 //-----------------------------------------------------------------------------
1343 // "button_press_event" from scrollbar
1344 //-----------------------------------------------------------------------------
1346 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1347 GdkEventButton
*WXUNUSED(gdk_event
),
1350 if (g_isIdle
) wxapp_install_idle_handler();
1352 // don't test here as we can release the mouse while being over
1353 // a different window then the slider
1355 // if (gdk_event->window != widget->slider) return FALSE;
1357 win
->m_isScrolling
= TRUE
;
1358 g_blockEventsOnScroll
= TRUE
;
1363 //-----------------------------------------------------------------------------
1364 // "button_release_event" from scrollbar
1365 //-----------------------------------------------------------------------------
1367 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1368 GdkEventButton
*WXUNUSED(gdk_event
),
1371 if (g_isIdle
) wxapp_install_idle_handler();
1373 // don't test here as we can release the mouse while being over
1374 // a different window then the slider
1376 // if (gdk_event->window != widget->slider) return FALSE;
1378 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1380 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1381 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1383 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1385 win
->m_isScrolling
= FALSE
;
1386 g_blockEventsOnScroll
= FALSE
;
1391 //-----------------------------------------------------------------------------
1392 // "realize" from m_widget
1393 //-----------------------------------------------------------------------------
1395 /* we cannot set colours, fonts and cursors before the widget has
1396 been realized, so we do this directly after realization */
1399 gtk_window_realized_callback( GtkWidget
*widget
, wxWindow
*win
)
1401 if (g_isIdle
) wxapp_install_idle_handler();
1403 if (win
->m_font
!= *wxSWISS_FONT
)
1405 wxFont
font( win
->m_font
);
1406 win
->m_font
= wxNullFont
;
1407 win
->SetFont( font
);
1410 if (win
->m_backgroundColour
!= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
))
1412 wxColour
bg( win
->m_backgroundColour
);
1413 win
->m_backgroundColour
= wxNullColour
;
1414 win
->SetBackgroundColour( bg
);
1417 if (win
->m_foregroundColour
!= *wxBLACK
)
1419 wxColour
fg( win
->m_foregroundColour
);
1420 win
->m_foregroundColour
= wxNullColour
;
1421 win
->SetForegroundColour( fg
);
1424 wxCursor
cursor( win
->m_cursor
);
1425 win
->m_cursor
= wxNullCursor
;
1426 win
->SetCursor( cursor
);
1431 //-----------------------------------------------------------------------------
1432 // InsertChild for wxWindow.
1433 //-----------------------------------------------------------------------------
1435 /* Callback for wxWindow. This very strange beast has to be used because
1436 * C++ has no virtual methods in a constructor. We have to emulate a
1437 * virtual function here as wxNotebook requires a different way to insert
1438 * a child in it. I had opted for creating a wxNotebookPage window class
1439 * which would have made this superfluous (such in the MDI window system),
1440 * but no-one was listening to me... */
1442 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1444 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1445 GTK_WIDGET(child
->m_widget
),
1451 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1453 /* we now allow a window to get the focus as long as it
1454 doesn't have any children. */
1455 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1459 //-----------------------------------------------------------------------------
1461 //-----------------------------------------------------------------------------
1463 wxWindow
* wxGetActiveWindow()
1465 return g_focusWindow
;
1468 //-----------------------------------------------------------------------------
1470 //-----------------------------------------------------------------------------
1472 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1474 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1475 EVT_SIZE(wxWindow::OnSize
)
1476 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1477 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1478 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1481 void wxWindow::Init()
1485 m_widget
= (GtkWidget
*) NULL
;
1486 m_wxwindow
= (GtkWidget
*) NULL
;
1487 m_parent
= (wxWindow
*) NULL
;
1488 m_children
.DeleteContents( FALSE
);
1501 m_eventHandler
= this;
1502 m_windowValidator
= (wxValidator
*) NULL
;
1506 m_cursor
= *wxSTANDARD_CURSOR
;
1507 m_font
= *wxSWISS_FONT
;
1509 m_windowName
= "noname";
1511 m_constraints
= (wxLayoutConstraints
*) NULL
;
1512 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1513 m_windowSizer
= (wxSizer
*) NULL
;
1514 m_sizerParent
= (wxWindow
*) NULL
;
1515 m_autoLayout
= FALSE
;
1519 m_needParent
= TRUE
;
1521 m_hasScrolling
= FALSE
;
1522 m_isScrolling
= FALSE
;
1523 m_hAdjust
= (GtkAdjustment
*) NULL
;
1524 m_vAdjust
= (GtkAdjustment
*) NULL
;
1525 m_oldHorizontalPos
= 0.0;
1526 m_oldVerticalPos
= 0.0;
1531 #if wxUSE_DRAG_AND_DROP
1532 m_dropTarget
= (wxDropTarget
*) NULL
;
1535 m_scrollGC
= (GdkGC
*) NULL
;
1536 m_widgetStyle
= (GtkStyle
*) NULL
;
1538 m_insertCallback
= wxInsertChildInWindow
;
1540 m_clientObject
= (wxClientData
*) NULL
;
1541 m_clientData
= NULL
;
1543 m_isStaticBox
= FALSE
;
1544 m_acceptsFocus
= FALSE
;
1547 m_toolTip
= (wxToolTip
*) NULL
;
1548 #endif // wxUSE_TOOLTIPS
1551 wxWindow::wxWindow()
1556 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1557 const wxPoint
&pos
, const wxSize
&size
,
1558 long style
, const wxString
&name
)
1562 Create( parent
, id
, pos
, size
, style
, name
);
1565 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1566 const wxPoint
&pos
, const wxSize
&size
,
1567 long style
, const wxString
&name
)
1569 wxASSERT_MSG( m_isWindow
, _T("Init() must have been called before!") );
1571 PreCreation( parent
, id
, pos
, size
, style
, name
);
1573 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1574 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1577 debug_focus_in( m_widget
, _T("wxWindow::m_widget"), name
);
1580 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1583 debug_focus_in( s_window
->hscrollbar
, _T("wxWindow::hsrcollbar"), name
);
1584 debug_focus_in( s_window
->vscrollbar
, _T("wxWindow::vsrcollbar"), name
);
1587 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1588 scroll_class
->scrollbar_spacing
= 0;
1590 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1592 m_oldHorizontalPos
= 0.0;
1593 m_oldVerticalPos
= 0.0;
1595 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1596 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1598 m_wxwindow
= gtk_myfixed_new();
1601 debug_focus_in( m_wxwindow
, _T("wxWindow::m_wxwindow"), name
);
1604 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1606 #if (GTK_MINOR_VERSION > 0)
1607 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1609 if (m_windowStyle
& wxRAISED_BORDER
)
1611 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1613 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1615 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1619 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1622 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1624 if (m_windowStyle
& wxRAISED_BORDER
)
1626 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1628 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1630 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1634 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1638 /* we always allow a window to get the focus as long as it
1639 doesn't have any children. */
1640 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1642 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1643 m_acceptsFocus
= FALSE
;
1647 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1648 m_acceptsFocus
= TRUE
;
1651 /* grab the actual focus */
1652 // gtk_widget_grab_focus( m_wxwindow );
1654 gtk_widget_show( m_wxwindow
);
1657 #if (GTK_MINOR_VERSION == 0)
1658 // shut the viewport up
1659 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1660 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1663 // I _really_ don't want scrollbars in the beginning
1664 m_vAdjust
->lower
= 0.0;
1665 m_vAdjust
->upper
= 1.0;
1666 m_vAdjust
->value
= 0.0;
1667 m_vAdjust
->step_increment
= 1.0;
1668 m_vAdjust
->page_increment
= 1.0;
1669 m_vAdjust
->page_size
= 5.0;
1670 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1671 m_hAdjust
->lower
= 0.0;
1672 m_hAdjust
->upper
= 1.0;
1673 m_hAdjust
->value
= 0.0;
1674 m_hAdjust
->step_increment
= 1.0;
1675 m_hAdjust
->page_increment
= 1.0;
1676 m_hAdjust
->page_size
= 5.0;
1677 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1679 // these handlers block mouse events to any window during scrolling
1680 // such as motion events and prevent GTK and wxWindows from fighting
1681 // over where the slider should be
1683 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1684 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1686 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1687 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1689 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1690 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1692 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1693 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1695 // these handlers get notified when screen updates are required either when
1696 // scrolling or when the window size (and therefore scrollbar configuration)
1699 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1700 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1701 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1702 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1704 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1705 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1706 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1707 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1709 if (m_parent
) m_parent
->AddChild( this );
1711 (m_parent
->m_insertCallback
)( m_parent
, this );
1720 wxWindow::~wxWindow()
1724 #if wxUSE_DRAG_AND_DROP
1727 delete m_dropTarget
;
1728 m_dropTarget
= (wxDropTarget
*) NULL
;
1736 m_toolTip
= (wxToolTip
*) NULL
;
1738 #endif // wxUSE_TOOLTIPS
1740 if (m_widget
) Show( FALSE
);
1744 if (m_parent
) m_parent
->RemoveChild( this );
1746 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1748 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1750 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1752 if (m_widget
) gtk_widget_destroy( m_widget
);
1754 DeleteRelatedConstraints();
1757 /* This removes any dangling pointers to this window
1758 * in other windows' constraintsInvolvedIn lists. */
1759 UnsetConstraints(m_constraints
);
1760 delete m_constraints
;
1761 m_constraints
= (wxLayoutConstraints
*) NULL
;
1766 delete m_windowSizer
;
1767 m_windowSizer
= (wxSizer
*) NULL
;
1769 /* If this is a child of a sizer, remove self from parent */
1770 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1772 /* Just in case the window has been Closed, but
1773 * we're then deleting immediately: don't leave
1774 * dangling pointers. */
1775 wxPendingDelete
.DeleteObject(this);
1777 /* Just in case we've loaded a top-level window via
1778 * wxWindow::LoadNativeDialog but we weren't a dialog
1780 wxTopLevelWindows
.DeleteObject(this);
1782 if (m_windowValidator
) delete m_windowValidator
;
1784 if (m_clientObject
) delete m_clientObject
;
1787 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1788 const wxPoint
&pos
, const wxSize
&size
,
1789 long style
, const wxString
&name
)
1791 wxASSERT_MSG( (!m_needParent
) || (parent
), _T("Need complete parent.") );
1793 m_widget
= (GtkWidget
*) NULL
;
1794 m_wxwindow
= (GtkWidget
*) NULL
;
1797 m_children
.DeleteContents( FALSE
);
1800 if (m_width
== -1) m_width
= 20;
1802 if (m_height
== -1) m_height
= 20;
1807 if (!m_needParent
) /* some reasonable defaults */
1811 m_x
= (gdk_screen_width () - m_width
) / 2;
1812 if (m_x
< 10) m_x
= 10;
1816 m_y
= (gdk_screen_height () - m_height
) / 2;
1817 if (m_y
< 10) m_y
= 10;
1828 m_eventHandler
= this;
1830 m_windowId
= id
== -1 ? wxNewId() : id
;
1834 m_cursor
= *wxSTANDARD_CURSOR
;
1835 m_font
= *wxSWISS_FONT
;
1836 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1837 m_foregroundColour
= *wxBLACK
;
1838 m_windowStyle
= style
;
1839 m_windowName
= name
;
1841 m_constraints
= (wxLayoutConstraints
*) NULL
;
1842 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1843 m_windowSizer
= (wxSizer
*) NULL
;
1844 m_sizerParent
= (wxWindow
*) NULL
;
1845 m_autoLayout
= FALSE
;
1847 m_hasScrolling
= FALSE
;
1848 m_isScrolling
= FALSE
;
1849 m_hAdjust
= (GtkAdjustment
*) NULL
;
1850 m_vAdjust
= (GtkAdjustment
*) NULL
;
1851 m_oldHorizontalPos
= 0.0;
1852 m_oldVerticalPos
= 0.0;
1857 #if wxUSE_DRAG_AND_DROP
1858 m_dropTarget
= (wxDropTarget
*) NULL
;
1861 m_windowValidator
= (wxValidator
*) NULL
;
1862 m_scrollGC
= (GdkGC
*) NULL
;
1863 m_widgetStyle
= (GtkStyle
*) NULL
;
1865 m_clientObject
= (wxClientData
*)NULL
;
1866 m_clientData
= NULL
;
1868 m_isStaticBox
= FALSE
;
1871 m_toolTip
= (wxToolTip
*) NULL
;
1872 #endif // wxUSE_TOOLTIPS
1875 void wxWindow::PostCreation()
1877 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1881 /* these get reported to wxWindows -> wxPaintEvent */
1882 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1883 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1885 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1886 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1888 #if (GTK_MINOR_VERSION > 0)
1889 /* these are called when the "sunken" or "raised" borders are drawn */
1890 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1891 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1893 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1894 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1898 GtkWidget
*connect_widget
= GetConnectWidget();
1900 ConnectWidget( connect_widget
);
1902 /* we cannot set colours, fonts and cursors before the widget has
1903 been realized, so we do this directly after realization */
1904 gtk_signal_connect( GTK_OBJECT(connect_widget
), "realize",
1905 GTK_SIGNAL_FUNC(gtk_window_realized_callback
), (gpointer
) this );
1910 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1912 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1913 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1915 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1916 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1918 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1919 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1921 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1922 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1924 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1925 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1927 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1928 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1930 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1931 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1933 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1934 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1936 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1937 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1940 bool wxWindow::HasVMT()
1945 bool wxWindow::Close( bool force
)
1947 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1949 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1950 event
.SetEventObject(this);
1951 event
.SetCanVeto(!force
);
1953 /* return FALSE if window wasn't closed because the application vetoed the
1955 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1958 bool wxWindow::Destroy()
1960 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1967 bool wxWindow::DestroyChildren()
1970 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1973 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1976 if (m_children
.Member(child
)) delete node
;
1982 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1984 // are we to set fonts here ?
1987 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1989 wxASSERT_MSG( (m_widget
!= NULL
), _T("invalid window") );
1990 wxASSERT_MSG( (m_parent
!= NULL
), _T("wxWindow::SetSize requires parent.\n") );
1992 if (m_resizing
) return; /* I don't like recursions */
1995 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook page */
1997 /* don't set the size for children of wxNotebook, just take the values. */
2005 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
2007 if (x
!= -1) m_x
= x
;
2008 if (y
!= -1) m_y
= y
;
2009 if (width
!= -1) m_width
= width
;
2010 if (height
!= -1) m_height
= height
;
2020 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
2022 if (width
== -1) m_width
= 80;
2025 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
2027 if (height
== -1) m_height
= 26;
2030 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
2031 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
2032 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
2033 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
2037 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
2039 /* the default button has a border around it */
2043 /* this is the result of hours of debugging: the following code
2044 means that if we have a m_wxwindow and we set the size of
2045 m_widget, m_widget (which is a GtkScrolledWindow) does NOT
2046 automatically propagate its size down to its m_wxwindow,
2047 which is its client area. therefore, we have to tell the
2048 client area directly that it has to resize itself.
2049 this will lead to that m_widget (GtkScrolledWindow) will
2050 calculate how much size it needs for scrollbars etc and
2051 it will then call XXX_size_allocate of its child, which
2052 is m_wxwindow. m_wxwindow in turn will do the same with its
2053 children and so on. problems can arise if this happens
2054 before all the children have been realized as some widgets
2055 stupidy need to be realized during XXX_size_allocate (e.g.
2056 GtkNotebook) and they will segv if called otherwise. this
2057 emergency is tested in gtk_myfixed_size_allocate. Normally
2058 this shouldn't be needed and only gtk_widget_queue_resize()
2059 should be enough to provoke a resize at the next appropriate
2060 moment, but this seems to fail, e.g. when a wxNotebook contains
2061 a wxSplitterWindow: the splitter window's children won't
2062 show up properly resized then. */
2064 gtk_myfixed_set_size( GTK_MYFIXED(m_parent
->m_wxwindow
),
2069 m_height
+2*border
);
2075 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
2076 event
.SetEventObject( this );
2077 GetEventHandler()->ProcessEvent( event
);
2082 void wxWindow::OnInternalIdle()
2087 void wxWindow::GetSize( int *width
, int *height
) const
2089 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2091 if (width
) (*width
) = m_width
;
2092 if (height
) (*height
) = m_height
;
2095 void wxWindow::DoSetClientSize( int width
, int height
)
2097 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2101 SetSize( width
, height
);
2108 if (!m_hasScrolling
)
2110 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2112 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2113 (m_windowStyle
& wxSUNKEN_BORDER
))
2115 dw
+= 2 * window_class
->xthickness
;
2116 dh
+= 2 * window_class
->ythickness
;
2121 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2122 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2124 #if (GTK_MINOR_VERSION == 0)
2125 GtkWidget
*viewport
= scroll_window
->viewport
;
2126 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2128 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2129 (m_windowStyle
& wxSUNKEN_BORDER
))
2131 dw
+= 2 * viewport_class
->xthickness
;
2132 dh
+= 2 * viewport_class
->ythickness
;
2137 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2138 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2140 we use this instead: range.slider_width = 11 + 2*2pts edge
2143 if (scroll_window
->vscrollbar_visible
)
2145 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2146 dw
+= scroll_class
->scrollbar_spacing
;
2149 if (scroll_window
->hscrollbar_visible
)
2151 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2152 dw
+= scroll_class
->scrollbar_spacing
;
2156 SetSize( width
+dw
, height
+dh
);
2160 void wxWindow::GetClientSize( int *width
, int *height
) const
2162 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2166 if (width
) (*width
) = m_width
;
2167 if (height
) (*height
) = m_height
;
2174 if (!m_hasScrolling
)
2176 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2178 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2179 (m_windowStyle
& wxSUNKEN_BORDER
))
2181 dw
+= 2 * window_class
->xthickness
;
2182 dh
+= 2 * window_class
->ythickness
;
2187 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2188 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2190 #if (GTK_MINOR_VERSION == 0)
2191 GtkWidget
*viewport
= scroll_window
->viewport
;
2192 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2194 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2195 (m_windowStyle
& wxSUNKEN_BORDER
))
2197 dw
+= 2 * viewport_class
->xthickness
;
2198 dh
+= 2 * viewport_class
->ythickness
;
2202 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2203 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2205 we use this instead: range.slider_width = 11 + 2*2pts edge
2208 if (scroll_window
->vscrollbar_visible
)
2210 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2211 dw
+= scroll_class
->scrollbar_spacing
;
2214 if (scroll_window
->hscrollbar_visible
)
2216 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2217 dh
+= scroll_class
->scrollbar_spacing
;
2221 if (width
) (*width
) = m_width
- dw
;
2222 if (height
) (*height
) = m_height
- dh
;
2226 void wxWindow::GetPosition( int *x
, int *y
) const
2228 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2234 void wxWindow::ClientToScreen( int *x
, int *y
)
2236 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2238 if (!m_widget
->window
) return;
2240 GdkWindow
*source
= (GdkWindow
*) NULL
;
2242 source
= m_wxwindow
->window
;
2244 source
= m_widget
->window
;
2248 gdk_window_get_origin( source
, &org_x
, &org_y
);
2252 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2254 org_x
+= m_widget
->allocation
.x
;
2255 org_y
+= m_widget
->allocation
.y
;
2263 void wxWindow::ScreenToClient( int *x
, int *y
)
2265 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2267 if (!m_widget
->window
) return;
2269 GdkWindow
*source
= (GdkWindow
*) NULL
;
2271 source
= m_wxwindow
->window
;
2273 source
= m_widget
->window
;
2277 gdk_window_get_origin( source
, &org_x
, &org_y
);
2281 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2283 org_x
+= m_widget
->allocation
.x
;
2284 org_y
+= m_widget
->allocation
.y
;
2292 void wxWindow::Centre( int direction
)
2294 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2303 m_parent
->GetSize( &p_w
, &p_h
);
2304 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2305 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2309 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2310 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2316 void wxWindow::Fit()
2318 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2322 wxNode
*node
= m_children
.First();
2325 wxWindow
*win
= (wxWindow
*)node
->Data();
2327 win
->GetPosition(&wx
, &wy
);
2328 win
->GetSize(&ww
, &wh
);
2329 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2330 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2332 node
= node
->Next();
2335 SetClientSize(maxX
+ 7, maxY
+ 14);
2338 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2340 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2348 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2350 /* this is commented because it also is commented
2351 in wxMSW. before I get even more questions about
2353 // if (GetAutoLayout()) Layout();
2356 bool wxWindow::Show( bool show
)
2358 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, _T("invalid window") );
2360 if (show
== m_isShown
) return TRUE
;
2363 gtk_widget_show( m_widget
);
2365 gtk_widget_hide( m_widget
);
2372 void wxWindow::Enable( bool enable
)
2374 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2376 m_isEnabled
= enable
;
2378 gtk_widget_set_sensitive( m_widget
, enable
);
2379 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2382 int wxWindow::GetCharHeight() const
2384 wxCHECK_MSG( (m_widget
!= NULL
), 12, _T("invalid window") );
2386 wxCHECK_MSG( m_font
.Ok(), 12, _T("invalid font") );
2388 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2390 return font
->ascent
+ font
->descent
;
2393 int wxWindow::GetCharWidth() const
2395 wxCHECK_MSG( (m_widget
!= NULL
), 8, _T("invalid window") );
2397 wxCHECK_MSG( m_font
.Ok(), 8, _T("invalid font") );
2399 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2401 return gdk_string_width( font
, "H" );
2404 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2405 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2407 wxFont fontToUse
= m_font
;
2408 if (theFont
) fontToUse
= *theFont
;
2410 wxCHECK_RET( fontToUse
.Ok(), _T("invalid font") );
2412 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2413 if (x
) (*x
) = gdk_string_width( font
, string
.mbc_str() );
2414 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2415 if (descent
) (*descent
) = font
->descent
;
2416 if (externalLeading
) (*externalLeading
) = 0; // ??
2419 void wxWindow::MakeModal( bool modal
)
2423 // Disable all other windows
2424 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2426 wxNode
*node
= wxTopLevelWindows
.First();
2429 wxWindow
*win
= (wxWindow
*)node
->Data();
2430 if (win
!= this) win
->Enable(!modal
);
2432 node
= node
->Next();
2437 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2439 event
.SetEventType( wxEVT_CHAR
);
2441 if (!GetEventHandler()->ProcessEvent( event
))
2447 void wxWindow::SetFocus()
2449 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2451 GtkWidget
*connect_widget
= GetConnectWidget();
2454 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2456 gtk_widget_grab_focus (connect_widget
);
2458 else if (GTK_IS_CONTAINER(connect_widget
))
2460 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2468 wxWindow
*wxWindow::FindFocus()
2470 return g_focusWindow
;
2473 bool wxWindow::AcceptsFocus() const
2475 return IsEnabled() && IsShown() && m_acceptsFocus
;
2478 void wxWindow::AddChild( wxWindow
*child
)
2480 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2481 wxCHECK_RET( (child
!= NULL
), _T("invalid child") );
2483 m_children
.Append( child
);
2486 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2488 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, _T("invalid window") );
2490 wxWindow
*oldParent
= GetParent();
2492 if (oldParent
) oldParent
->RemoveChild( this );
2494 gtk_widget_unparent( m_widget
);
2498 newParent
->AddChild( this );
2499 (newParent
->m_insertCallback
)( newParent
, this );
2505 void wxWindow::RemoveChild( wxWindow
*child
)
2507 m_children
.DeleteObject( child
);
2508 child
->m_parent
= (wxWindow
*) NULL
;
2511 void wxWindow::SetReturnCode( int retCode
)
2513 m_retCode
= retCode
;
2516 int wxWindow::GetReturnCode()
2521 void wxWindow::Raise()
2523 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2525 if (!m_widget
->window
) return;
2527 if (m_widget
) gdk_window_raise( m_widget
->window
);
2530 void wxWindow::Lower()
2532 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2534 if (!m_widget
->window
) return;
2536 if (m_widget
) gdk_window_lower( m_widget
->window
);
2539 wxEvtHandler
*wxWindow::GetEventHandler() const
2541 return m_eventHandler
;
2544 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2546 m_eventHandler
= handler
;
2549 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2551 handler
->SetNextHandler(GetEventHandler());
2552 SetEventHandler(handler
);
2555 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2557 if (GetEventHandler())
2559 wxEvtHandler
*handlerA
= GetEventHandler();
2560 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2561 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2562 SetEventHandler(handlerB
);
2566 return (wxEvtHandler
*) NULL
;
2572 return (wxEvtHandler
*) NULL
;
2575 wxValidator
*wxWindow::GetValidator()
2577 return m_windowValidator
;
2580 void wxWindow::SetValidator( const wxValidator
& validator
)
2582 if (m_windowValidator
) delete m_windowValidator
;
2583 m_windowValidator
= (wxValidator
*)validator
.Clone();
2584 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2587 void wxWindow::SetClientObject( wxClientData
*data
)
2589 if (m_clientObject
) delete m_clientObject
;
2590 m_clientObject
= data
;
2593 wxClientData
*wxWindow::GetClientObject()
2595 return m_clientObject
;
2598 void wxWindow::SetClientData( void *data
)
2600 m_clientData
= data
;
2603 void *wxWindow::GetClientData()
2605 return m_clientData
;
2608 bool wxWindow::IsBeingDeleted()
2613 void wxWindow::SetId( wxWindowID id
)
2618 wxWindowID
wxWindow::GetId() const
2623 void wxWindow::SetCursor( const wxCursor
&cursor
)
2625 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2629 if (cursor
== m_cursor
) return;
2634 m_cursor
= *wxSTANDARD_CURSOR
;
2637 if (!m_widget
->window
) return;
2639 gdk_window_set_cursor( m_widget
->window
, m_cursor
.GetCursor() );
2641 if ((m_wxwindow
) && (m_wxwindow
->window
))
2642 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
.GetCursor() );
2645 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2650 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2652 wxCHECK_RET( (m_widget
!= NULL
), _T("invalid window") );
2654 if (!m_widget
->window
) return;
2656 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2660 gdk_window_clear_area( m_wxwindow
->window
,
2662 rect
->width
, rect
->height
);
2666 gdk_window_clear( m_wxwindow
->window
);
2673 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2675 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2679 GdkRectangle gdk_rect
;
2680 gdk_rect
.x
= rect
->x
;
2681 gdk_rect
.y
= rect
->y
;
2682 gdk_rect
.width
= rect
->width
;
2683 gdk_rect
.height
= rect
->height
;
2686 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2688 gtk_widget_draw( m_widget
, &gdk_rect
);
2692 wxRegion
wxWindow::GetUpdateRegion() const
2694 return m_updateRegion
;
2697 bool wxWindow::IsExposed( int x
, int y
) const
2699 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2702 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2704 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2707 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2709 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2712 bool wxWindow::IsExposed( const wxRect
& rect
) const
2714 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2717 void wxWindow::Clear()
2719 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2721 if (!m_widget
->window
) return;
2723 if (m_wxwindow
&& m_wxwindow
->window
)
2725 gdk_window_clear( m_wxwindow
->window
);
2730 void wxWindow::SetToolTip( const wxString
&tip
)
2734 m_toolTip
->SetTip( tip
);
2738 SetToolTip( new wxToolTip( tip
) );
2741 // setting empty tooltip text does not remove the tooltip any more for
2742 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2745 void wxWindow::SetToolTip( wxToolTip
*tip
)
2749 m_toolTip
->SetTip( (char*) NULL
);
2756 m_toolTip
->Apply( this );
2759 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const wxChar
*tip
)
2761 gtk_tooltips_set_tip( tips
, GetConnectWidget(), wxConv_current
->cWX2MB(tip
), (gchar
*) NULL
);
2763 #endif // wxUSE_TOOLTIPS
2765 wxColour
wxWindow::GetBackgroundColour() const
2767 return m_backgroundColour
;
2770 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2772 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2774 if (m_backgroundColour
== colour
) return;
2776 m_backgroundColour
= colour
;
2777 if (!m_backgroundColour
.Ok()) return;
2779 GtkWidget
*connect_widget
= GetConnectWidget();
2780 if (!connect_widget
->window
) return;
2782 if (m_wxwindow
&& m_wxwindow
->window
)
2784 /* wxMSW doesn't clear the window here. I don't do that
2785 either to provide compatibility. call Clear() to do
2788 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2789 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2792 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2794 if (sysbg
.Red() == colour
.Red() &&
2795 sysbg
.Green() == colour
.Green() &&
2796 sysbg
.Blue() == colour
.Blue())
2798 m_backgroundColour
= wxNullColour
;
2800 m_backgroundColour
= sysbg
;
2808 wxColour
wxWindow::GetForegroundColour() const
2810 return m_foregroundColour
;
2813 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2815 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2817 if (m_foregroundColour
== colour
) return;
2819 m_foregroundColour
= colour
;
2820 if (!m_foregroundColour
.Ok()) return;
2822 if (!m_widget
->window
) return;
2824 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2825 if (sysbg
.Red() == colour
.Red() &&
2826 sysbg
.Green() == colour
.Green() &&
2827 sysbg
.Blue() == colour
.Blue())
2829 m_backgroundColour
= wxNullColour
;
2831 m_backgroundColour
= sysbg
;
2839 GtkStyle
*wxWindow::GetWidgetStyle()
2841 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2845 gtk_widget_get_style( m_widget
) );
2847 return m_widgetStyle
;
2850 void wxWindow::SetWidgetStyle()
2852 GtkStyle
*style
= GetWidgetStyle();
2854 gdk_font_unref( style
->font
);
2855 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2857 if (m_foregroundColour
.Ok())
2859 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2860 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2861 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2862 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2865 if (m_backgroundColour
.Ok())
2867 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2868 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2869 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2870 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2871 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2872 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2873 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2874 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2875 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2879 void wxWindow::ApplyWidgetStyle()
2883 bool wxWindow::Validate()
2885 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2887 wxNode
*node
= m_children
.First();
2890 wxWindow
*child
= (wxWindow
*)node
->Data();
2891 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2895 node
= node
->Next();
2900 bool wxWindow::TransferDataToWindow()
2902 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2904 wxNode
*node
= m_children
.First();
2907 wxWindow
*child
= (wxWindow
*)node
->Data();
2908 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2909 !child
->GetValidator()->TransferToWindow() )
2911 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2914 node
= node
->Next();
2919 bool wxWindow::TransferDataFromWindow()
2921 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2923 wxNode
*node
= m_children
.First();
2926 wxWindow
*child
= (wxWindow
*)node
->Data();
2927 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2931 node
= node
->Next();
2936 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2938 m_acceleratorTable
= accel
;
2941 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2943 TransferDataToWindow();
2946 void wxWindow::InitDialog()
2948 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
2950 wxInitDialogEvent
event(GetId());
2951 event
.SetEventObject( this );
2952 GetEventHandler()->ProcessEvent(event
);
2955 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2957 menu
->SetInvokingWindow( win
);
2958 wxNode
*node
= menu
->GetItems().First();
2961 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2962 if (menuitem
->IsSubMenu())
2964 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2966 node
= node
->Next();
2970 static gint gs_pop_x
= 0;
2971 static gint gs_pop_y
= 0;
2973 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2975 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2980 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2982 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, _T("invalid window") );
2984 wxCHECK_MSG( menu
!= NULL
, FALSE
, _T("invalid popup-menu") );
2986 SetInvokingWindow( menu
, this );
2994 GTK_MENU(menu
->m_menu
),
2995 (GtkWidget
*) NULL
, // parent menu shell
2996 (GtkWidget
*) NULL
, // parent menu item
2997 (GtkMenuPositionFunc
) pop_pos_callback
,
2998 (gpointer
) this, // client data
2999 0, // button used to activate it
3000 0 //gs_timeLastClick // the time of activation
3005 #if wxUSE_DRAG_AND_DROP
3007 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
3009 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3011 GtkWidget
*dnd_widget
= GetConnectWidget();
3013 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
3015 if (m_dropTarget
) delete m_dropTarget
;
3016 m_dropTarget
= dropTarget
;
3018 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
3021 wxDropTarget
*wxWindow::GetDropTarget() const
3023 return m_dropTarget
;
3028 GtkWidget
* wxWindow::GetConnectWidget()
3030 GtkWidget
*connect_widget
= m_widget
;
3031 if (m_wxwindow
) connect_widget
= m_wxwindow
;
3033 return connect_widget
;
3036 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
3038 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
3039 return (window
== m_widget
->window
);
3042 void wxWindow::SetFont( const wxFont
&font
)
3044 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3046 if (m_font
== font
) return;
3048 if (((wxFont
*)&font
)->Ok())
3051 m_font
= *wxSWISS_FONT
;
3053 if (!m_widget
->window
) return;
3055 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
3056 if (sysbg
.Red() == m_backgroundColour
.Red() &&
3057 sysbg
.Green() == m_backgroundColour
.Green() &&
3058 sysbg
.Blue() == m_backgroundColour
.Blue())
3060 m_backgroundColour
= wxNullColour
;
3062 m_backgroundColour
= sysbg
;
3070 void wxWindow::SetWindowStyleFlag( long flag
)
3072 m_windowStyle
= flag
;
3075 long wxWindow::GetWindowStyleFlag() const
3077 return m_windowStyle
;
3080 void wxWindow::CaptureMouse()
3082 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3084 wxCHECK_RET( g_capturing
== FALSE
, _T("CaptureMouse called twice") );
3086 if (!m_widget
->window
) return;
3088 GtkWidget
*connect_widget
= GetConnectWidget();
3089 gtk_grab_add( connect_widget
);
3090 gdk_pointer_grab( connect_widget
->window
, FALSE
,
3092 (GDK_BUTTON_PRESS_MASK
|
3093 GDK_BUTTON_RELEASE_MASK
|
3094 GDK_POINTER_MOTION_MASK
),
3101 void wxWindow::ReleaseMouse()
3103 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3105 wxCHECK_RET( g_capturing
== TRUE
, _T("ReleaseMouse called twice") );
3107 if (!m_widget
->window
) return;
3109 GtkWidget
*connect_widget
= GetConnectWidget();
3110 gtk_grab_remove( connect_widget
);
3111 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
3112 g_capturing
= FALSE
;
3115 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
3119 wxString
wxWindow::GetTitle() const
3121 return (wxString
&)m_windowName
;
3124 wxString
wxWindow::GetLabel() const
3129 void wxWindow::SetName( const wxString
&name
)
3131 m_windowName
= name
;
3134 wxString
wxWindow::GetName() const
3136 return (wxString
&)m_windowName
;
3139 bool wxWindow::IsShown() const
3144 bool wxWindow::IsRetained()
3149 wxWindow
*wxWindow::FindWindow( long id
)
3151 if (id
== m_windowId
) return this;
3152 wxNode
*node
= m_children
.First();
3155 wxWindow
*child
= (wxWindow
*)node
->Data();
3156 wxWindow
*res
= child
->FindWindow( id
);
3157 if (res
) return res
;
3158 node
= node
->Next();
3160 return (wxWindow
*) NULL
;
3163 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
3165 if (name
== m_windowName
) return this;
3166 wxNode
*node
= m_children
.First();
3169 wxWindow
*child
= (wxWindow
*)node
->Data();
3170 wxWindow
*res
= child
->FindWindow( name
);
3171 if (res
) return res
;
3172 node
= node
->Next();
3174 return (wxWindow
*) NULL
;
3177 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
3178 int range
, bool refresh
)
3180 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3182 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3184 m_hasScrolling
= TRUE
;
3186 if (orient
== wxHORIZONTAL
)
3188 float fpos
= (float)pos
;
3189 float frange
= (float)range
;
3190 float fthumb
= (float)thumbVisible
;
3191 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3192 if (fpos
< 0.0) fpos
= 0.0;
3194 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3195 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3197 SetScrollPos( orient
, pos
, refresh
);
3201 m_oldHorizontalPos
= fpos
;
3203 m_hAdjust
->lower
= 0.0;
3204 m_hAdjust
->upper
= frange
;
3205 m_hAdjust
->value
= fpos
;
3206 m_hAdjust
->step_increment
= 1.0;
3207 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3208 m_hAdjust
->page_size
= fthumb
;
3212 float fpos
= (float)pos
;
3213 float frange
= (float)range
;
3214 float fthumb
= (float)thumbVisible
;
3215 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3216 if (fpos
< 0.0) fpos
= 0.0;
3218 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3219 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3221 SetScrollPos( orient
, pos
, refresh
);
3225 m_oldVerticalPos
= fpos
;
3227 m_vAdjust
->lower
= 0.0;
3228 m_vAdjust
->upper
= frange
;
3229 m_vAdjust
->value
= fpos
;
3230 m_vAdjust
->step_increment
= 1.0;
3231 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3232 m_vAdjust
->page_size
= fthumb
;
3237 if (orient
== wxHORIZONTAL
)
3238 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3240 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3242 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3246 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3248 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3250 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3252 if (orient
== wxHORIZONTAL
)
3254 float fpos
= (float)pos
;
3255 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3256 if (fpos
< 0.0) fpos
= 0.0;
3257 m_oldHorizontalPos
= fpos
;
3259 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3260 m_hAdjust
->value
= fpos
;
3264 float fpos
= (float)pos
;
3265 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3266 if (fpos
< 0.0) fpos
= 0.0;
3267 m_oldVerticalPos
= fpos
;
3269 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3270 m_vAdjust
->value
= fpos
;
3275 if (m_wxwindow
->window
)
3277 if (orient
== wxHORIZONTAL
)
3278 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3280 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3285 int wxWindow::GetScrollThumb( int orient
) const
3287 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3289 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3291 if (orient
== wxHORIZONTAL
)
3292 return (int)(m_hAdjust
->page_size
+0.5);
3294 return (int)(m_vAdjust
->page_size
+0.5);
3297 int wxWindow::GetScrollPos( int orient
) const
3299 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3301 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3303 if (orient
== wxHORIZONTAL
)
3304 return (int)(m_hAdjust
->value
+0.5);
3306 return (int)(m_vAdjust
->value
+0.5);
3309 int wxWindow::GetScrollRange( int orient
) const
3311 wxCHECK_MSG( m_widget
!= NULL
, 0, _T("invalid window") );
3313 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, _T("window needs client area for scrolling") );
3315 if (orient
== wxHORIZONTAL
)
3316 return (int)(m_hAdjust
->upper
+0.5);
3318 return (int)(m_vAdjust
->upper
+0.5);
3321 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3323 wxCHECK_RET( m_widget
!= NULL
, _T("invalid window") );
3325 wxCHECK_RET( m_wxwindow
!= NULL
, _T("window needs client area for scrolling") );
3327 wxNode
*node
= m_children
.First();
3330 wxWindow
*child
= (wxWindow
*) node
->Data();
3331 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
3332 node
= node
->Next();
3337 GetClientSize( &cw
, &ch
);
3339 int w
= cw
- abs(dx
);
3340 int h
= ch
- abs(dy
);
3341 if ((h
< 0) || (w
< 0))
3348 if (dx
< 0) s_x
= -dx
;
3349 if (dy
< 0) s_y
= -dy
;
3352 if (dx
> 0) d_x
= dx
;
3353 if (dy
> 0) d_y
= dy
;
3357 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3358 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3361 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3362 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3365 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3366 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3367 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3368 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3370 Refresh( TRUE
, &rect
);
3373 //-------------------------------------------------------------------------------------
3375 //-------------------------------------------------------------------------------------
3377 wxLayoutConstraints
*wxWindow::GetConstraints() const
3379 return m_constraints
;
3382 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3386 UnsetConstraints(m_constraints
);
3387 delete m_constraints
;
3389 m_constraints
= constraints
;
3392 // Make sure other windows know they're part of a 'meaningful relationship'
3393 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3394 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3395 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3396 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3397 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3398 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3399 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3400 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3401 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3402 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3403 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3404 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3405 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3406 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3407 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3408 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3414 void wxWindow::SetAutoLayout( bool autoLayout
)
3416 m_autoLayout
= autoLayout
;
3419 bool wxWindow::GetAutoLayout() const
3421 return m_autoLayout
;
3424 wxSizer
*wxWindow::GetSizer() const
3426 return m_windowSizer
;
3429 void wxWindow::SetSizerParent( wxWindow
*win
)
3431 m_sizerParent
= win
;
3434 wxWindow
*wxWindow::GetSizerParent() const
3436 return m_sizerParent
;
3439 // This removes any dangling pointers to this window
3440 // in other windows' constraintsInvolvedIn lists.
3441 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3445 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3446 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3447 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3448 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3449 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3450 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3451 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3452 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3453 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3454 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3455 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3456 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3457 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3458 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3459 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3460 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3464 // Back-pointer to other windows we're involved with, so if we delete
3465 // this window, we must delete any constraints we're involved with.
3466 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3468 if (!m_constraintsInvolvedIn
)
3469 m_constraintsInvolvedIn
= new wxList
;
3470 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3471 m_constraintsInvolvedIn
->Append(otherWin
);
3474 // REMOVE back-pointer to other windows we're involved with.
3475 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3477 if (m_constraintsInvolvedIn
)
3478 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3481 // Reset any constraints that mention this window
3482 void wxWindow::DeleteRelatedConstraints()
3484 if (m_constraintsInvolvedIn
)
3486 wxNode
*node
= m_constraintsInvolvedIn
->First();
3489 wxWindow
*win
= (wxWindow
*)node
->Data();
3490 wxNode
*next
= node
->Next();
3491 wxLayoutConstraints
*constr
= win
->GetConstraints();
3493 // Reset any constraints involving this window
3496 constr
->left
.ResetIfWin((wxWindow
*)this);
3497 constr
->top
.ResetIfWin((wxWindow
*)this);
3498 constr
->right
.ResetIfWin((wxWindow
*)this);
3499 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3500 constr
->width
.ResetIfWin((wxWindow
*)this);
3501 constr
->height
.ResetIfWin((wxWindow
*)this);
3502 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3503 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3508 delete m_constraintsInvolvedIn
;
3509 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3513 void wxWindow::SetSizer(wxSizer
*sizer
)
3515 m_windowSizer
= sizer
;
3517 sizer
->SetSizerParent((wxWindow
*)this);
3524 bool wxWindow::Layout()
3526 if (GetConstraints())
3529 GetClientSize(&w
, &h
);
3530 GetConstraints()->width
.SetValue(w
);
3531 GetConstraints()->height
.SetValue(h
);
3534 // If top level (one sizer), evaluate the sizer's constraints.
3538 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3539 GetSizer()->LayoutPhase1(&noChanges
);
3540 GetSizer()->LayoutPhase2(&noChanges
);
3541 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3547 // Otherwise, evaluate child constraints
3548 ResetConstraints(); // Mark all constraints as unevaluated
3549 DoPhase(1); // Just one phase need if no sizers involved
3551 SetConstraintSizes(); // Recursively set the real window sizes
3557 // Do a phase of evaluating constraints:
3558 // the default behaviour. wxSizers may do a similar
3559 // thing, but also impose their own 'constraints'
3560 // and order the evaluation differently.
3561 bool wxWindow::LayoutPhase1(int *noChanges
)
3563 wxLayoutConstraints
*constr
= GetConstraints();
3566 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3572 bool wxWindow::LayoutPhase2(int *noChanges
)
3582 // Do a phase of evaluating child constraints
3583 bool wxWindow::DoPhase(int phase
)
3585 int noIterations
= 0;
3586 int maxIterations
= 500;
3590 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3594 wxNode
*node
= m_children
.First();
3597 wxWindow
*child
= (wxWindow
*)node
->Data();
3598 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3600 wxLayoutConstraints
*constr
= child
->GetConstraints();
3603 if (succeeded
.Member(child
))
3608 int tempNoChanges
= 0;
3609 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3610 noChanges
+= tempNoChanges
;
3613 succeeded
.Append(child
);
3618 node
= node
->Next();
3625 void wxWindow::ResetConstraints()
3627 wxLayoutConstraints
*constr
= GetConstraints();
3630 constr
->left
.SetDone(FALSE
);
3631 constr
->top
.SetDone(FALSE
);
3632 constr
->right
.SetDone(FALSE
);
3633 constr
->bottom
.SetDone(FALSE
);
3634 constr
->width
.SetDone(FALSE
);
3635 constr
->height
.SetDone(FALSE
);
3636 constr
->centreX
.SetDone(FALSE
);
3637 constr
->centreY
.SetDone(FALSE
);
3639 wxNode
*node
= m_children
.First();
3642 wxWindow
*win
= (wxWindow
*)node
->Data();
3643 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3644 win
->ResetConstraints();
3645 node
= node
->Next();
3649 // Need to distinguish between setting the 'fake' size for
3650 // windows and sizers, and setting the real values.
3651 void wxWindow::SetConstraintSizes(bool recurse
)
3653 wxLayoutConstraints
*constr
= GetConstraints();
3654 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3655 constr
->width
.GetDone() && constr
->height
.GetDone())
3657 int x
= constr
->left
.GetValue();
3658 int y
= constr
->top
.GetValue();
3659 int w
= constr
->width
.GetValue();
3660 int h
= constr
->height
.GetValue();
3662 // If we don't want to resize this window, just move it...
3663 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3664 (constr
->height
.GetRelationship() != wxAsIs
))
3666 // Calls Layout() recursively. AAAGH. How can we stop that.
3667 // Simply take Layout() out of non-top level OnSizes.
3668 SizerSetSize(x
, y
, w
, h
);
3677 wxChar
*windowClass
= this->GetClassInfo()->GetClassName();
3680 if (GetName() == _T(""))
3681 winName
= _T("unnamed");
3683 winName
= GetName();
3684 wxLogDebug( _T("Constraint(s) not satisfied for window of type %s, name %s:\n"),
3685 (const wxChar
*)windowClass
,
3686 (const wxChar
*)winName
);
3687 if (!constr
->left
.GetDone()) wxLogDebug( _T(" unsatisfied 'left' constraint.\n") );
3688 if (!constr
->right
.GetDone()) wxLogDebug( _T(" unsatisfied 'right' constraint.\n") );
3689 if (!constr
->width
.GetDone()) wxLogDebug( _T(" unsatisfied 'width' constraint.\n") );
3690 if (!constr
->height
.GetDone()) wxLogDebug( _T(" unsatisfied 'height' constraint.\n") );
3691 wxLogDebug( _T("Please check constraints: try adding AsIs() constraints.\n") );
3696 wxNode
*node
= m_children
.First();
3699 wxWindow
*win
= (wxWindow
*)node
->Data();
3700 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3701 win
->SetConstraintSizes();
3702 node
= node
->Next();
3707 // This assumes that all sizers are 'on' the same
3708 // window, i.e. the parent of this window.
3709 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3711 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3712 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3716 m_sizerParent
->GetPosition(&xp
, &yp
);
3717 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3722 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3726 TransformSizerToActual(&xx
, &yy
);
3727 SetSize(xx
, yy
, w
, h
);
3730 void wxWindow::SizerMove(int x
, int y
)
3734 TransformSizerToActual(&xx
, &yy
);
3738 // Only set the size/position of the constraint (if any)
3739 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3741 wxLayoutConstraints
*constr
= GetConstraints();
3746 constr
->left
.SetValue(x
);
3747 constr
->left
.SetDone(TRUE
);
3751 constr
->top
.SetValue(y
);
3752 constr
->top
.SetDone(TRUE
);
3756 constr
->width
.SetValue(w
);
3757 constr
->width
.SetDone(TRUE
);
3761 constr
->height
.SetValue(h
);
3762 constr
->height
.SetDone(TRUE
);
3767 void wxWindow::MoveConstraint(int x
, int y
)
3769 wxLayoutConstraints
*constr
= GetConstraints();
3774 constr
->left
.SetValue(x
);
3775 constr
->left
.SetDone(TRUE
);
3779 constr
->top
.SetValue(y
);
3780 constr
->top
.SetDone(TRUE
);
3785 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3787 wxLayoutConstraints
*constr
= GetConstraints();
3790 *w
= constr
->width
.GetValue();
3791 *h
= constr
->height
.GetValue();
3797 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3799 wxLayoutConstraints
*constr
= GetConstraints();
3802 *w
= constr
->width
.GetValue();
3803 *h
= constr
->height
.GetValue();
3806 GetClientSize(w
, h
);
3809 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3811 wxLayoutConstraints
*constr
= GetConstraints();
3814 *x
= constr
->left
.GetValue();
3815 *y
= constr
->top
.GetValue();