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 //-------------------------------------------------------------------------
128 #define FRAME_BORDER_WIDTH 2
130 //-----------------------------------------------------------------------------
132 //-----------------------------------------------------------------------------
134 extern wxList wxPendingDelete
;
135 extern bool g_blockEventsOnDrag
;
136 extern bool g_blockEventsOnScroll
;
137 static bool g_capturing
= FALSE
;
138 static wxWindow
*g_focusWindow
= (wxWindow
*) NULL
;
140 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
141 the last click here */
142 static guint32 gs_timeLastClick
= 0;
144 //-----------------------------------------------------------------------------
145 // local code (see below)
146 //-----------------------------------------------------------------------------
148 static void draw_frame( GtkWidget
*widget
, wxWindow
*win
)
150 if (!win
->HasVMT()) return;
155 if (win
->m_hasScrolling
)
157 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(widget
);
158 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget
)->klass
);
161 GtkWidget *hscrollbar = scroll_window->hscrollbar;
162 GtkWidget *vscrollbar = scroll_window->vscrollbar;
164 we use this instead: range.slider_width = 11 + 2*2pts edge
167 if (scroll_window
->vscrollbar_visible
)
169 dw
+= 15; /* dw += vscrollbar->allocation.width; */
170 dw
+= scroll_class
->scrollbar_spacing
;
173 if (scroll_window
->hscrollbar_visible
)
175 dh
+= 15; /* dh += hscrollbar->allocation.height; */
176 dw
+= scroll_class
->scrollbar_spacing
;
182 if (GTK_WIDGET_NO_WINDOW (widget
))
184 dx
+= widget
->allocation
.x
;
185 dy
+= widget
->allocation
.y
;
188 if (win
->m_windowStyle
& wxRAISED_BORDER
)
190 gtk_draw_shadow( widget
->style
,
195 win
->m_width
-dw
, win
->m_height
-dh
);
199 if (win
->m_windowStyle
& wxSUNKEN_BORDER
)
201 gtk_draw_shadow( widget
->style
,
206 win
->m_width
-dw
, win
->m_height
-dh
);
211 //-----------------------------------------------------------------------------
212 // "expose_event" of m_widget
213 //-----------------------------------------------------------------------------
215 static void gtk_window_own_expose_callback( GtkWidget
*widget
, GdkEventExpose
*gdk_event
, wxWindow
*win
)
217 if (gdk_event
->count
> 0) return;
218 draw_frame( widget
, win
);
221 //-----------------------------------------------------------------------------
222 // "draw" of m_wxwindow
223 //-----------------------------------------------------------------------------
225 static void gtk_window_own_draw_callback( GtkWidget
*widget
, GdkRectangle
*WXUNUSED(rect
), wxWindow
*win
)
227 draw_frame( widget
, win
);
230 //-----------------------------------------------------------------------------
231 // "expose_event" of m_wxwindow
232 //-----------------------------------------------------------------------------
234 static void gtk_window_expose_callback( GtkWidget
*WXUNUSED(widget
), GdkEventExpose
*gdk_event
, wxWindow
*win
)
236 if (!win
->HasVMT()) return;
238 win
->m_updateRegion
.Union( gdk_event
->area
.x
,
240 gdk_event
->area
.width
,
241 gdk_event
->area
.height
);
243 if (gdk_event
->count
> 0) return;
246 printf( "OnExpose from " );
247 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
248 printf( win->GetClassInfo()->GetClassName() );
252 wxPaintEvent
event( win
->GetId() );
253 event
.SetEventObject( win
);
254 win
->GetEventHandler()->ProcessEvent( event
);
256 win
->m_updateRegion
.Clear();
259 //-----------------------------------------------------------------------------
260 // "draw" of m_wxwindow
261 //-----------------------------------------------------------------------------
263 static void gtk_window_draw_callback( GtkWidget
*WXUNUSED(widget
), GdkRectangle
*rect
, wxWindow
*win
)
265 if (!win
->HasVMT()) return;
267 win
->m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
269 wxPaintEvent
event( win
->GetId() );
270 event
.SetEventObject( win
);
271 win
->GetEventHandler()->ProcessEvent( event
);
273 win
->m_updateRegion
.Clear();
276 //-----------------------------------------------------------------------------
277 // "key_press_event" from any window
278 //-----------------------------------------------------------------------------
280 static gint
gtk_window_key_press_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
282 if (!win
->HasVMT()) return FALSE
;
283 if (g_blockEventsOnDrag
) return FALSE
;
286 printf( "OnKeyPress from " );
287 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
288 printf( win->GetClassInfo()->GetClassName() );
293 switch (gdk_event
->keyval
)
295 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
296 case GDK_ISO_Left_Tab
:
298 case GDK_Tab
: key_code
= WXK_TAB
; break;
299 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
300 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
301 case GDK_Return
: key_code
= WXK_RETURN
; break;
302 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
303 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
304 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
305 case GDK_Delete
: key_code
= WXK_DELETE
; break;
306 case GDK_Home
: key_code
= WXK_HOME
; break;
307 case GDK_Left
: key_code
= WXK_LEFT
; break;
308 case GDK_Up
: key_code
= WXK_UP
; break;
309 case GDK_Right
: key_code
= WXK_RIGHT
; break;
310 case GDK_Down
: key_code
= WXK_DOWN
; break;
311 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
312 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
313 case GDK_Next
: key_code
= WXK_NEXT
; break;
314 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
315 case GDK_End
: key_code
= WXK_END
; break;
316 case GDK_Begin
: key_code
= WXK_HOME
; break;
317 case GDK_Select
: key_code
= WXK_SELECT
; break;
318 case GDK_Print
: key_code
= WXK_PRINT
; break;
319 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
320 case GDK_Insert
: key_code
= WXK_INSERT
; break;
321 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
322 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
323 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
324 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
325 case GDK_KP_Up
: key_code
= WXK_UP
; break;
326 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
327 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
328 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
329 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
330 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
331 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
332 case GDK_KP_End
: key_code
= WXK_END
; break;
333 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
334 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
335 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
336 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
337 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
338 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
339 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
340 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
341 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
342 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
343 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
344 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
345 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
346 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
347 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
348 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
349 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
350 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
351 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
352 case GDK_F1
: key_code
= WXK_F1
; break;
353 case GDK_F2
: key_code
= WXK_F2
; break;
354 case GDK_F3
: key_code
= WXK_F3
; break;
355 case GDK_F4
: key_code
= WXK_F4
; break;
356 case GDK_F5
: key_code
= WXK_F5
; break;
357 case GDK_F6
: key_code
= WXK_F6
; break;
358 case GDK_F7
: key_code
= WXK_F7
; break;
359 case GDK_F8
: key_code
= WXK_F8
; break;
360 case GDK_F9
: key_code
= WXK_F9
; break;
361 case GDK_F10
: key_code
= WXK_F10
; break;
362 case GDK_F11
: key_code
= WXK_F11
; break;
363 case GDK_F12
: key_code
= WXK_F12
; break;
366 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
367 key_code
= gdk_event
->keyval
;
371 if (!key_code
) return FALSE
;
373 wxKeyEvent
event( wxEVT_KEY_DOWN
);
374 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
375 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
376 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
377 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
378 event
.m_keyCode
= key_code
;
381 event
.SetEventObject( win
);
383 bool ret
= win
->GetEventHandler()->ProcessEvent( event
);
387 wxWindow
*ancestor
= win
;
390 int command
= ancestor
->GetAcceleratorTable()->GetCommand( event
);
393 wxCommandEvent
command_event( wxEVT_COMMAND_MENU_SELECTED
, command
);
394 ret
= ancestor
->GetEventHandler()->ProcessEvent( command_event
);
397 ancestor
= ancestor
->GetParent();
401 // win is a control: tab can be propagated up
403 ((gdk_event
->keyval
== GDK_Tab
) || (gdk_event
->keyval
== GDK_ISO_Left_Tab
)) &&
404 ((win
->m_windowStyle
& wxTE_PROCESS_TAB
) == 0))
406 wxNavigationKeyEvent new_event
;
407 /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
408 new_event
.SetDirection( (gdk_event
->keyval
== GDK_Tab
) );
409 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
410 new_event
.SetWindowChange( (gdk_event
->state
& GDK_CONTROL_MASK
) );
411 new_event
.SetCurrentFocus( win
);
412 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
416 (gdk_event
->keyval
== GDK_Escape
) )
418 wxCommandEvent
new_event(wxEVT_COMMAND_BUTTON_CLICKED
,wxID_CANCEL
);
419 new_event
.SetEventObject( win
);
420 ret
= win
->GetEventHandler()->ProcessEvent( new_event
);
424 Damn, I forgot why this didn't work, but it didn't work.
426 // win is a panel: up can be propagated to the panel
427 if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) &&
428 (gdk_event->keyval == GDK_Up))
430 win->m_parent->SetFocus();
434 // win is a panel: left/right can be propagated to the panel
435 if ((!ret) && (win->m_wxwindow) &&
436 ((gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Left) ||
437 (gdk_event->keyval == GDK_Up) || (gdk_event->keyval == GDK_Down)))
439 wxNavigationKeyEvent new_event;
440 new_event.SetDirection( (gdk_event->keyval == GDK_Right) || (gdk_event->keyval == GDK_Down) );
441 new_event.SetCurrentFocus( win );
442 ret = win->GetEventHandler()->ProcessEvent( new_event );
448 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_press_event" );
455 //-----------------------------------------------------------------------------
456 // "key_release_event" from any window
457 //-----------------------------------------------------------------------------
459 static gint
gtk_window_key_release_callback( GtkWidget
*widget
, GdkEventKey
*gdk_event
, wxWindow
*win
)
461 if (!win
->HasVMT()) return FALSE
;
462 if (g_blockEventsOnDrag
) return FALSE
;
465 printf( "OnKeyRelease from " );
466 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
467 printf( win->GetClassInfo()->GetClassName() );
472 switch (gdk_event
->keyval
)
474 case GDK_BackSpace
: key_code
= WXK_BACK
; break;
475 case GDK_ISO_Left_Tab
:
477 case GDK_Tab
: key_code
= WXK_TAB
; break;
478 case GDK_Linefeed
: key_code
= WXK_RETURN
; break;
479 case GDK_Clear
: key_code
= WXK_CLEAR
; break;
480 case GDK_Return
: key_code
= WXK_RETURN
; break;
481 case GDK_Pause
: key_code
= WXK_PAUSE
; break;
482 case GDK_Scroll_Lock
: key_code
= WXK_SCROLL
; break;
483 case GDK_Escape
: key_code
= WXK_ESCAPE
; break;
484 case GDK_Delete
: key_code
= WXK_DELETE
; break;
485 case GDK_Home
: key_code
= WXK_HOME
; break;
486 case GDK_Left
: key_code
= WXK_LEFT
; break;
487 case GDK_Up
: key_code
= WXK_UP
; break;
488 case GDK_Right
: key_code
= WXK_RIGHT
; break;
489 case GDK_Down
: key_code
= WXK_DOWN
; break;
490 case GDK_Prior
: key_code
= WXK_PRIOR
; break;
491 // case GDK_Page_Up: key_code = WXK_PAGEUP; break;
492 case GDK_Next
: key_code
= WXK_NEXT
; break;
493 // case GDK_Page_Down: key_code = WXK_PAGEDOWN; break;
494 case GDK_End
: key_code
= WXK_END
; break;
495 case GDK_Begin
: key_code
= WXK_HOME
; break;
496 case GDK_Select
: key_code
= WXK_SELECT
; break;
497 case GDK_Print
: key_code
= WXK_PRINT
; break;
498 case GDK_Execute
: key_code
= WXK_EXECUTE
; break;
499 case GDK_Insert
: key_code
= WXK_INSERT
; break;
500 case GDK_Num_Lock
: key_code
= WXK_NUMLOCK
; break;
501 case GDK_KP_Enter
: key_code
= WXK_RETURN
; break;
502 case GDK_KP_Home
: key_code
= WXK_HOME
; break;
503 case GDK_KP_Left
: key_code
= WXK_LEFT
; break;
504 case GDK_KP_Up
: key_code
= WXK_UP
; break;
505 case GDK_KP_Right
: key_code
= WXK_RIGHT
; break;
506 case GDK_KP_Down
: key_code
= WXK_DOWN
; break;
507 case GDK_KP_Prior
: key_code
= WXK_PRIOR
; break;
508 // case GDK_KP_Page_Up: key_code = WXK_PAGEUP; break;
509 case GDK_KP_Next
: key_code
= WXK_NEXT
; break;
510 // case GDK_KP_Page_Down: key_code = WXK_PAGEDOWN; break;
511 case GDK_KP_End
: key_code
= WXK_END
; break;
512 case GDK_KP_Begin
: key_code
= WXK_HOME
; break;
513 case GDK_KP_Insert
: key_code
= WXK_INSERT
; break;
514 case GDK_KP_Delete
: key_code
= WXK_DELETE
; break;
515 case GDK_KP_Multiply
: key_code
= WXK_MULTIPLY
; break;
516 case GDK_KP_Add
: key_code
= WXK_ADD
; break;
517 case GDK_KP_Separator
: key_code
= WXK_SEPARATOR
; break;
518 case GDK_KP_Subtract
: key_code
= WXK_SUBTRACT
; break;
519 case GDK_KP_Decimal
: key_code
= WXK_DECIMAL
; break;
520 case GDK_KP_Divide
: key_code
= WXK_DIVIDE
; break;
521 case GDK_KP_0
: key_code
= WXK_NUMPAD0
; break;
522 case GDK_KP_1
: key_code
= WXK_NUMPAD1
; break;
523 case GDK_KP_2
: key_code
= WXK_NUMPAD2
; break;
524 case GDK_KP_3
: key_code
= WXK_NUMPAD3
; break;
525 case GDK_KP_4
: key_code
= WXK_NUMPAD4
; break;
526 case GDK_KP_5
: key_code
= WXK_NUMPAD5
; break;
527 case GDK_KP_6
: key_code
= WXK_NUMPAD6
; break;
528 case GDK_KP_7
: key_code
= WXK_NUMPAD7
; break;
529 case GDK_KP_8
: key_code
= WXK_NUMPAD7
; break;
530 case GDK_KP_9
: key_code
= WXK_NUMPAD9
; break;
531 case GDK_F1
: key_code
= WXK_F1
; break;
532 case GDK_F2
: key_code
= WXK_F2
; break;
533 case GDK_F3
: key_code
= WXK_F3
; break;
534 case GDK_F4
: key_code
= WXK_F4
; break;
535 case GDK_F5
: key_code
= WXK_F5
; break;
536 case GDK_F6
: key_code
= WXK_F6
; break;
537 case GDK_F7
: key_code
= WXK_F7
; break;
538 case GDK_F8
: key_code
= WXK_F8
; break;
539 case GDK_F9
: key_code
= WXK_F9
; break;
540 case GDK_F10
: key_code
= WXK_F10
; break;
541 case GDK_F11
: key_code
= WXK_F11
; break;
542 case GDK_F12
: key_code
= WXK_F12
; break;
545 if ((gdk_event
->keyval
>= 0x20) && (gdk_event
->keyval
<= 0xFF))
546 key_code
= gdk_event
->keyval
;
550 if (!key_code
) return FALSE
;
552 wxKeyEvent
event( wxEVT_KEY_UP
);
553 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
554 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
555 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
556 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
557 event
.m_keyCode
= key_code
;
560 event
.SetEventObject( win
);
562 if (win
->GetEventHandler()->ProcessEvent( event
))
564 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "key_release_event" );
571 //-----------------------------------------------------------------------------
572 // "button_press_event"
573 //-----------------------------------------------------------------------------
575 static gint
gtk_window_button_press_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
577 if (!win
->HasVMT()) return FALSE
;
578 if (g_blockEventsOnDrag
) return TRUE
;
579 if (g_blockEventsOnScroll
) return TRUE
;
581 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
585 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
) && !GTK_WIDGET_HAS_FOCUS (win
->m_wxwindow
) )
587 gtk_widget_grab_focus (win
->m_wxwindow
);
590 printf( "GrabFocus from " );
591 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
592 printf( win->GetClassInfo()->GetClassName() );
600 printf( "OnButtonPress from " );
601 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
602 printf( win->GetClassInfo()->GetClassName() );
606 wxEventType event_type
= wxEVT_LEFT_DOWN
;
608 if (gdk_event
->button
== 1)
610 switch (gdk_event
->type
)
612 case GDK_BUTTON_PRESS
: event_type
= wxEVT_LEFT_DOWN
; break;
613 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_LEFT_DCLICK
; break;
617 else if (gdk_event
->button
== 2)
619 switch (gdk_event
->type
)
621 case GDK_BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DOWN
; break;
622 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_MIDDLE_DCLICK
; break;
626 else if (gdk_event
->button
== 3)
628 switch (gdk_event
->type
)
630 case GDK_BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DOWN
; break;
631 case GDK_2BUTTON_PRESS
: event_type
= wxEVT_RIGHT_DCLICK
; break;
636 wxMouseEvent
event( event_type
);
637 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
638 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
639 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
640 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
641 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
642 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
643 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
645 event
.m_x
= (long)gdk_event
->x
;
646 event
.m_y
= (long)gdk_event
->y
;
648 // Some control don't have their own X window and thus cannot get
653 wxNode
*node
= win
->GetChildren().First();
656 wxWindow
*child
= (wxWindow
*)node
->Data();
658 if (child
->m_isStaticBox
)
660 // wxStaticBox is transparent in the box itself
663 int xx1
= child
->m_x
;
664 int yy1
= child
->m_y
;
665 int xx2
= child
->m_x
+ child
->m_width
;
666 int yy2
= child
->m_x
+ child
->m_height
;
669 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
671 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
673 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
675 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
678 event
.m_x
-= child
->m_x
;
679 event
.m_y
-= child
->m_y
;
686 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
687 (child
->m_x
<= event
.m_x
) &&
688 (child
->m_y
<= event
.m_y
) &&
689 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
690 (child
->m_y
+child
->m_height
>= event
.m_y
))
693 event
.m_x
-= child
->m_x
;
694 event
.m_y
-= child
->m_y
;
702 event
.SetEventObject( win
);
704 gs_timeLastClick
= gdk_event
->time
;
706 if (win
->GetEventHandler()->ProcessEvent( event
))
708 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_press_event" );
715 //-----------------------------------------------------------------------------
716 // "button_release_event"
717 //-----------------------------------------------------------------------------
719 static gint
gtk_window_button_release_callback( GtkWidget
*widget
, GdkEventButton
*gdk_event
, wxWindow
*win
)
721 if (!win
->HasVMT()) return FALSE
;
722 if (g_blockEventsOnDrag
) return FALSE
;
723 if (g_blockEventsOnScroll
) return FALSE
;
725 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
728 printf( "OnButtonRelease from " );
729 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
730 printf( win->GetClassInfo()->GetClassName() );
734 wxEventType event_type
= wxEVT_NULL
;
736 switch (gdk_event
->button
)
738 case 1: event_type
= wxEVT_LEFT_UP
; break;
739 case 2: event_type
= wxEVT_MIDDLE_UP
; break;
740 case 3: event_type
= wxEVT_RIGHT_UP
; break;
743 wxMouseEvent
event( event_type
);
744 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
745 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
746 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
747 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
748 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
749 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
750 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
751 event
.m_x
= (long)gdk_event
->x
;
752 event
.m_y
= (long)gdk_event
->y
;
754 // Some control don't have their own X window and thus cannot get
759 wxNode
*node
= win
->GetChildren().First();
762 wxWindow
*child
= (wxWindow
*)node
->Data();
764 if (child
->m_isStaticBox
)
766 // wxStaticBox is transparent in the box itself
769 int xx1
= child
->m_x
;
770 int yy1
= child
->m_y
;
771 int xx2
= child
->m_x
+ child
->m_width
;
772 int yy2
= child
->m_x
+ child
->m_height
;
775 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
777 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
779 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
781 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
784 event
.m_x
-= child
->m_x
;
785 event
.m_y
-= child
->m_y
;
792 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
793 (child
->m_x
<= event
.m_x
) &&
794 (child
->m_y
<= event
.m_y
) &&
795 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
796 (child
->m_y
+child
->m_height
>= event
.m_y
))
799 event
.m_x
-= child
->m_x
;
800 event
.m_y
-= child
->m_y
;
808 event
.SetEventObject( win
);
810 if (win
->GetEventHandler()->ProcessEvent( event
))
812 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "button_release_event" );
819 //-----------------------------------------------------------------------------
820 // "motion_notify_event"
821 //-----------------------------------------------------------------------------
823 static gint
gtk_window_motion_notify_callback( GtkWidget
*widget
, GdkEventMotion
*gdk_event
, wxWindow
*win
)
825 if (!win
->HasVMT()) return FALSE
;
826 if (g_blockEventsOnDrag
) return FALSE
;
827 if (g_blockEventsOnScroll
) return FALSE
;
829 if (!win
->IsOwnGtkWindow( gdk_event
->window
)) return FALSE
;
831 if (gdk_event
->is_hint
)
835 GdkModifierType state
;
836 gdk_window_get_pointer(gdk_event
->window
, &x
, &y
, &state
);
839 gdk_event
->state
= state
;
843 printf( "OnMotion from " );
844 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
845 printf( win->GetClassInfo()->GetClassName() );
849 wxMouseEvent
event( wxEVT_MOTION
);
850 event
.m_shiftDown
= (gdk_event
->state
& GDK_SHIFT_MASK
);
851 event
.m_controlDown
= (gdk_event
->state
& GDK_CONTROL_MASK
);
852 event
.m_altDown
= (gdk_event
->state
& GDK_MOD1_MASK
);
853 event
.m_metaDown
= (gdk_event
->state
& GDK_MOD2_MASK
);
854 event
.m_leftDown
= (gdk_event
->state
& GDK_BUTTON1_MASK
);
855 event
.m_middleDown
= (gdk_event
->state
& GDK_BUTTON2_MASK
);
856 event
.m_rightDown
= (gdk_event
->state
& GDK_BUTTON3_MASK
);
858 event
.m_x
= (long)gdk_event
->x
;
859 event
.m_y
= (long)gdk_event
->y
;
861 // Some control don't have their own X window and thus cannot get
866 wxNode
*node
= win
->GetChildren().First();
869 wxWindow
*child
= (wxWindow
*)node
->Data();
871 if (child
->m_isStaticBox
)
873 // wxStaticBox is transparent in the box itself
876 int xx1
= child
->m_x
;
877 int yy1
= child
->m_y
;
878 int xx2
= child
->m_x
+ child
->m_width
;
879 int yy2
= child
->m_x
+ child
->m_height
;
882 if (((x
>= xx1
) && (x
<= xx1
+10) && (y
>= yy1
) && (y
<= yy2
)) ||
884 ((x
>= xx2
-10) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy2
)) ||
886 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy1
) && (y
<= yy1
+10)) ||
888 ((x
>= xx1
) && (x
<= xx2
) && (y
>= yy2
-1) && (y
<= yy2
)))
891 event
.m_x
-= child
->m_x
;
892 event
.m_y
-= child
->m_y
;
899 if ((child
->m_wxwindow
== (GtkWidget
*) NULL
) &&
900 (child
->m_x
<= event
.m_x
) &&
901 (child
->m_y
<= event
.m_y
) &&
902 (child
->m_x
+child
->m_width
>= event
.m_x
) &&
903 (child
->m_y
+child
->m_height
>= event
.m_y
))
906 event
.m_x
-= child
->m_x
;
907 event
.m_y
-= child
->m_y
;
915 event
.SetEventObject( win
);
917 if (win
->GetEventHandler()->ProcessEvent( event
))
919 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "motion_notify_event" );
926 //-----------------------------------------------------------------------------
928 //-----------------------------------------------------------------------------
930 static gint
gtk_window_focus_in_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
932 if (!win
->HasVMT()) return FALSE
;
933 if (g_blockEventsOnDrag
) return FALSE
;
939 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
941 GTK_WIDGET_SET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
943 printf( "SetFocus flag from " );
944 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
945 printf( win->GetClassInfo()->GetClassName() );
953 printf( "OnSetFocus from " );
954 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
955 printf( win->GetClassInfo()->GetClassName() );
957 printf( WXSTRINGCAST win->GetLabel() );
961 wxFocusEvent
event( wxEVT_SET_FOCUS
, win
->GetId() );
962 event
.SetEventObject( win
);
964 if (win
->GetEventHandler()->ProcessEvent( event
))
966 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_in_event" );
973 //-----------------------------------------------------------------------------
975 //-----------------------------------------------------------------------------
977 static gint
gtk_window_focus_out_callback( GtkWidget
*widget
, GdkEvent
*WXUNUSED(event
), wxWindow
*win
)
979 if (!win
->HasVMT()) return FALSE
;
980 if (g_blockEventsOnDrag
) return FALSE
;
984 if (GTK_WIDGET_CAN_FOCUS(win
->m_wxwindow
))
985 GTK_WIDGET_UNSET_FLAGS (win
->m_wxwindow
, GTK_HAS_FOCUS
);
989 printf( "OnKillFocus from " );
990 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
991 printf( win->GetClassInfo()->GetClassName() );
995 wxFocusEvent
event( wxEVT_KILL_FOCUS
, win
->GetId() );
996 event
.SetEventObject( win
);
998 if (win
->GetEventHandler()->ProcessEvent( event
))
1000 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "focus_out_event" );
1007 //-----------------------------------------------------------------------------
1008 // "enter_notify_event"
1009 //-----------------------------------------------------------------------------
1011 static gint
gtk_window_enter_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1013 if (!win
->HasVMT()) return FALSE
;
1014 if (g_blockEventsOnDrag
) return FALSE
;
1016 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1018 if ((widget
->window
) && (win
->m_cursor
))
1019 gdk_window_set_cursor( widget
->window
, win
->m_cursor
->GetCursor() );
1022 printf( "OnEnter from " );
1023 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1024 printf( win->GetClassInfo()->GetClassName() );
1028 wxMouseEvent
event( wxEVT_ENTER_WINDOW
);
1029 event
.SetEventObject( win
);
1033 GdkModifierType state
= (GdkModifierType
)0;
1035 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1037 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1038 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1039 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1040 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1041 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1042 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1043 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1045 event
.m_x
= (long)x
;
1046 event
.m_y
= (long)y
;
1048 if (win
->GetEventHandler()->ProcessEvent( event
))
1050 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "enter_notify_event" );
1057 //-----------------------------------------------------------------------------
1058 // "leave_notify_event"
1059 //-----------------------------------------------------------------------------
1061 static gint
gtk_window_leave_callback( GtkWidget
*widget
, GdkEventCrossing
*gdk_event
, wxWindow
*win
)
1063 if (!win
->HasVMT()) return FALSE
;
1064 if (g_blockEventsOnDrag
) return FALSE
;
1066 if (widget
->window
!= gdk_event
->window
) return FALSE
;
1068 if ((widget
->window
) && (win
->m_cursor
))
1069 gdk_window_set_cursor( widget
->window
, wxSTANDARD_CURSOR
->GetCursor() );
1072 printf( "OnLeave from " );
1073 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1074 printf( win->GetClassInfo()->GetClassName() );
1078 wxMouseEvent
event( wxEVT_LEAVE_WINDOW
);
1079 event
.SetEventObject( win
);
1083 GdkModifierType state
= (GdkModifierType
)0;
1085 gdk_window_get_pointer( widget
->window
, &x
, &y
, &state
);
1087 event
.m_shiftDown
= (state
& GDK_SHIFT_MASK
);
1088 event
.m_controlDown
= (state
& GDK_CONTROL_MASK
);
1089 event
.m_altDown
= (state
& GDK_MOD1_MASK
);
1090 event
.m_metaDown
= (state
& GDK_MOD2_MASK
);
1091 event
.m_leftDown
= (state
& GDK_BUTTON1_MASK
);
1092 event
.m_middleDown
= (state
& GDK_BUTTON2_MASK
);
1093 event
.m_rightDown
= (state
& GDK_BUTTON3_MASK
);
1095 event
.m_x
= (long)x
;
1096 event
.m_y
= (long)y
;
1098 if (win
->GetEventHandler()->ProcessEvent( event
))
1100 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget
), "leave_notify_event" );
1107 //-----------------------------------------------------------------------------
1108 // "value_changed" from m_vAdjust
1109 //-----------------------------------------------------------------------------
1111 static void gtk_window_vscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1113 if (g_blockEventsOnDrag
) return;
1116 printf( "OnVScroll from " );
1117 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1118 printf( win->GetClassInfo()->GetClassName() );
1122 if (!win
->HasVMT()) return;
1124 float diff
= win
->m_vAdjust
->value
- win
->m_oldVerticalPos
;
1125 if (fabs(diff
) < 0.2) return;
1126 win
->m_oldVerticalPos
= win
->m_vAdjust
->value
;
1128 wxEventType command
= wxEVT_NULL
;
1130 float line_step
= win
->m_vAdjust
->step_increment
;
1131 float page_step
= win
->m_vAdjust
->page_increment
;
1133 if (win
->m_isScrolling
)
1135 command
= wxEVT_SCROLL_THUMBTRACK
;
1139 if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1140 else if (fabs(win
->m_vAdjust
->value
-win
->m_vAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1141 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1142 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1143 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1144 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1145 else command
= wxEVT_SCROLL_THUMBTRACK
;
1148 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1150 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1151 event
.SetEventObject( win
);
1152 win
->GetEventHandler()->ProcessEvent( event
);
1155 //-----------------------------------------------------------------------------
1156 // "value_changed" from m_hAdjust
1157 //-----------------------------------------------------------------------------
1159 static void gtk_window_hscroll_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1161 if (g_blockEventsOnDrag
) return;
1164 printf( "OnHScroll from " );
1165 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1166 printf( win->GetClassInfo()->GetClassName() );
1170 if (!win
->HasVMT()) return;
1172 float diff
= win
->m_hAdjust
->value
- win
->m_oldHorizontalPos
;
1173 if (fabs(diff
) < 0.2) return;
1174 win
->m_oldHorizontalPos
= win
->m_hAdjust
->value
;
1176 wxEventType command
= wxEVT_NULL
;
1178 float line_step
= win
->m_hAdjust
->step_increment
;
1179 float page_step
= win
->m_hAdjust
->page_increment
;
1181 if (win
->m_isScrolling
)
1183 command
= wxEVT_SCROLL_THUMBTRACK
;
1187 if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->lower
) < 0.2) command
= wxEVT_SCROLL_BOTTOM
;
1188 else if (fabs(win
->m_hAdjust
->value
-win
->m_hAdjust
->upper
) < 0.2) command
= wxEVT_SCROLL_TOP
;
1189 else if (fabs(diff
-line_step
) < 0.2) command
= wxEVT_SCROLL_LINEDOWN
;
1190 else if (fabs(diff
+line_step
) < 0.2) command
= wxEVT_SCROLL_LINEUP
;
1191 else if (fabs(diff
-page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEDOWN
;
1192 else if (fabs(diff
+page_step
) < 0.2) command
= wxEVT_SCROLL_PAGEUP
;
1193 else command
= wxEVT_SCROLL_THUMBTRACK
;
1196 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1198 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1199 event
.SetEventObject( win
);
1200 win
->GetEventHandler()->ProcessEvent( event
);
1203 //-----------------------------------------------------------------------------
1204 // "changed" from m_vAdjust
1205 //-----------------------------------------------------------------------------
1207 static void gtk_window_vscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1209 if (g_blockEventsOnDrag
) return;
1212 printf( "OnVScroll change from " );
1213 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1214 printf( win->GetClassInfo()->GetClassName() );
1218 if (!win
->HasVMT()) return;
1220 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1221 int value
= (int)(win
->m_vAdjust
->value
+0.5);
1223 wxScrollEvent
event( command
, win
->GetId(), value
, wxVERTICAL
);
1224 event
.SetEventObject( win
);
1225 win
->GetEventHandler()->ProcessEvent( event
);
1228 //-----------------------------------------------------------------------------
1229 // "changed" from m_hAdjust
1230 //-----------------------------------------------------------------------------
1232 static void gtk_window_hscroll_change_callback( GtkWidget
*WXUNUSED(widget
), wxWindow
*win
)
1234 if (g_blockEventsOnDrag
) return;
1237 printf( "OnHScroll change from " );
1238 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
1239 printf( win->GetClassInfo()->GetClassName() );
1243 if (!win
->HasVMT()) return;
1245 wxEventType command
= wxEVT_SCROLL_THUMBTRACK
;
1246 int value
= (int)(win
->m_hAdjust
->value
+0.5);
1248 wxScrollEvent
event( command
, win
->GetId(), value
, wxHORIZONTAL
);
1249 event
.SetEventObject( win
);
1250 win
->GetEventHandler()->ProcessEvent( event
);
1253 //-----------------------------------------------------------------------------
1254 // "button_press_event" from scrollbar
1255 //-----------------------------------------------------------------------------
1257 static gint
gtk_scrollbar_button_press_callback( GtkRange
*WXUNUSED(widget
),
1258 GdkEventButton
*WXUNUSED(gdk_event
),
1261 // don't test here as we can release the mouse while being over
1262 // a different window then the slider
1264 // if (gdk_event->window != widget->slider) return FALSE;
1266 win
->m_isScrolling
= TRUE
;
1267 g_blockEventsOnScroll
= TRUE
;
1272 //-----------------------------------------------------------------------------
1273 // "button_release_event" from scrollbar
1274 //-----------------------------------------------------------------------------
1276 static gint
gtk_scrollbar_button_release_callback( GtkRange
*widget
,
1277 GdkEventButton
*WXUNUSED(gdk_event
),
1281 // don't test here as we can release the mouse while being over
1282 // a different window then the slider
1284 // if (gdk_event->window != widget->slider) return FALSE;
1286 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(win
->m_widget
);
1288 if (widget
== GTK_RANGE(s_window
->vscrollbar
))
1289 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_hAdjust
), "value_changed" );
1291 gtk_signal_emit_by_name( GTK_OBJECT(win
->m_vAdjust
), "value_changed" );
1293 win
->m_isScrolling
= FALSE
;
1294 g_blockEventsOnScroll
= FALSE
;
1299 //-----------------------------------------------------------------------------
1300 // InsertChild for wxWindow.
1301 //-----------------------------------------------------------------------------
1303 /* Callback for wxWindow. This very strange beast has to be used because
1304 * C++ has no virtual methods in a constructor. We have to emulate a
1305 * virtual function here as wxNotebook requires a different way to insert
1306 * a child in it. I had opted for creating a wxNotebookPage window class
1307 * which would have made this superfluous (such in the MDI window system),
1308 * but no-one was listening to me... */
1310 static void wxInsertChildInWindow( wxWindow
* parent
, wxWindow
* child
)
1312 gtk_myfixed_put( GTK_MYFIXED(parent
->m_wxwindow
),
1313 GTK_WIDGET(child
->m_widget
),
1317 gtk_widget_set_usize( GTK_WIDGET(child
->m_widget
),
1321 if (parent
->m_windowStyle
& wxTAB_TRAVERSAL
)
1323 /* we now allow a window to get the focus as long as it
1324 doesn't have any children. */
1325 GTK_WIDGET_UNSET_FLAGS( parent
->m_wxwindow
, GTK_CAN_FOCUS
);
1329 //-----------------------------------------------------------------------------
1331 //-----------------------------------------------------------------------------
1333 wxWindow
* wxGetActiveWindow()
1335 return g_focusWindow
;
1338 //-----------------------------------------------------------------------------
1340 //-----------------------------------------------------------------------------
1342 IMPLEMENT_DYNAMIC_CLASS(wxWindow
,wxEvtHandler
)
1344 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
1345 EVT_SIZE(wxWindow::OnSize
)
1346 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
1347 EVT_INIT_DIALOG(wxWindow::OnInitDialog
)
1348 EVT_KEY_DOWN(wxWindow::OnKeyDown
)
1351 void wxWindow::Init()
1355 m_widget
= (GtkWidget
*) NULL
;
1356 m_wxwindow
= (GtkWidget
*) NULL
;
1357 m_parent
= (wxWindow
*) NULL
;
1358 m_children
.DeleteContents( FALSE
);
1371 m_eventHandler
= this;
1372 m_windowValidator
= (wxValidator
*) NULL
;
1376 m_cursor
= (wxCursor
*) NULL
;
1377 m_font
= *wxSWISS_FONT
;
1379 m_windowName
= "noname";
1381 m_constraints
= (wxLayoutConstraints
*) NULL
;
1382 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1383 m_windowSizer
= (wxSizer
*) NULL
;
1384 m_sizerParent
= (wxWindow
*) NULL
;
1385 m_autoLayout
= FALSE
;
1389 m_needParent
= TRUE
;
1391 m_hasScrolling
= FALSE
;
1392 m_isScrolling
= FALSE
;
1393 m_hAdjust
= (GtkAdjustment
*) NULL
;
1394 m_vAdjust
= (GtkAdjustment
*) NULL
;
1395 m_oldHorizontalPos
= 0.0;
1396 m_oldVerticalPos
= 0.0;
1401 #if wxUSE_DRAG_AND_DROP
1402 m_dropTarget
= (wxDropTarget
*) NULL
;
1405 m_scrollGC
= (GdkGC
*) NULL
;
1406 m_widgetStyle
= (GtkStyle
*) NULL
;
1408 m_insertCallback
= wxInsertChildInWindow
;
1410 m_clientObject
= (wxClientData
*) NULL
;
1411 m_clientData
= NULL
;
1413 m_isStaticBox
= FALSE
;
1414 m_acceptsFocus
= FALSE
;
1417 m_toolTip
= (wxToolTip
*) NULL
;
1418 #endif // wxUSE_TOOLTIPS
1421 wxWindow::wxWindow()
1426 wxWindow::wxWindow( wxWindow
*parent
, wxWindowID id
,
1427 const wxPoint
&pos
, const wxSize
&size
,
1428 long style
, const wxString
&name
)
1432 Create( parent
, id
, pos
, size
, style
, name
);
1435 bool wxWindow::Create( wxWindow
*parent
, wxWindowID id
,
1436 const wxPoint
&pos
, const wxSize
&size
,
1437 long style
, const wxString
&name
)
1439 wxASSERT_MSG( m_isWindow
, "Init() must have been called before!" );
1441 PreCreation( parent
, id
, pos
, size
, style
, name
);
1443 m_widget
= gtk_scrolled_window_new( (GtkAdjustment
*) NULL
, (GtkAdjustment
*) NULL
);
1444 GTK_WIDGET_UNSET_FLAGS( m_widget
, GTK_CAN_FOCUS
);
1446 GtkScrolledWindow
*s_window
= GTK_SCROLLED_WINDOW(m_widget
);
1448 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1449 scroll_class
->scrollbar_spacing
= 0;
1451 gtk_scrolled_window_set_policy( s_window
, GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
1453 m_oldHorizontalPos
= 0.0;
1454 m_oldVerticalPos
= 0.0;
1456 m_hAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->hscrollbar
) );
1457 m_vAdjust
= gtk_range_get_adjustment( GTK_RANGE(s_window
->vscrollbar
) );
1459 m_wxwindow
= gtk_myfixed_new();
1461 gtk_container_add( GTK_CONTAINER(m_widget
), m_wxwindow
);
1463 #if (GTK_MINOR_VERSION > 0)
1464 GtkMyFixed
*myfixed
= GTK_MYFIXED(m_wxwindow
);
1466 if (m_windowStyle
& wxRAISED_BORDER
)
1468 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_OUT
);
1470 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1472 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_IN
);
1476 gtk_myfixed_set_shadow_type( myfixed
, GTK_SHADOW_NONE
);
1479 GtkViewport
*viewport
= GTK_VIEWPORT(s_window
->viewport
);
1481 if (m_windowStyle
& wxRAISED_BORDER
)
1483 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_OUT
);
1485 else if (m_windowStyle
& wxSUNKEN_BORDER
)
1487 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_IN
);
1491 gtk_viewport_set_shadow_type( viewport
, GTK_SHADOW_NONE
);
1495 if (m_windowStyle
& wxTAB_TRAVERSAL
)
1497 /* we now allow a window to get the focus as long as it
1498 doesn't have any children. */
1499 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1500 m_acceptsFocus
= FALSE
;
1504 GTK_WIDGET_SET_FLAGS( m_wxwindow
, GTK_CAN_FOCUS
);
1505 m_acceptsFocus
= TRUE
;
1508 #if (GTK_MINOR_VERSION == 0)
1509 // shut the viewport up
1510 gtk_viewport_set_hadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1511 gtk_viewport_set_vadjustment( viewport
, (GtkAdjustment
*) gtk_adjustment_new( 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) );
1514 // I _really_ don't want scrollbars in the beginning
1515 m_vAdjust
->lower
= 0.0;
1516 m_vAdjust
->upper
= 1.0;
1517 m_vAdjust
->value
= 0.0;
1518 m_vAdjust
->step_increment
= 1.0;
1519 m_vAdjust
->page_increment
= 1.0;
1520 m_vAdjust
->page_size
= 5.0;
1521 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
1522 m_hAdjust
->lower
= 0.0;
1523 m_hAdjust
->upper
= 1.0;
1524 m_hAdjust
->value
= 0.0;
1525 m_hAdjust
->step_increment
= 1.0;
1526 m_hAdjust
->page_increment
= 1.0;
1527 m_hAdjust
->page_size
= 5.0;
1528 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
1530 // these handlers block mouse events to any window during scrolling
1531 // such as motion events and prevent GTK and wxWindows from fighting
1532 // over where the slider should be
1534 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_press_event",
1535 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1537 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_press_event",
1538 (GtkSignalFunc
)gtk_scrollbar_button_press_callback
, (gpointer
) this );
1540 gtk_signal_connect( GTK_OBJECT(s_window
->vscrollbar
), "button_release_event",
1541 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1543 gtk_signal_connect( GTK_OBJECT(s_window
->hscrollbar
), "button_release_event",
1544 (GtkSignalFunc
)gtk_scrollbar_button_release_callback
, (gpointer
) this );
1546 // these handlers get notified when screen updates are required either when
1547 // scrolling or when the window size (and therefore scrollbar configuration)
1550 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "value_changed",
1551 (GtkSignalFunc
) gtk_window_hscroll_callback
, (gpointer
) this );
1552 gtk_signal_connect( GTK_OBJECT(m_vAdjust
), "value_changed",
1553 (GtkSignalFunc
) gtk_window_vscroll_callback
, (gpointer
) this );
1555 gtk_signal_connect( GTK_OBJECT(m_hAdjust
), "changed",
1556 (GtkSignalFunc
) gtk_window_hscroll_change_callback
, (gpointer
) this );
1557 gtk_signal_connect(GTK_OBJECT(m_vAdjust
), "changed",
1558 (GtkSignalFunc
) gtk_window_vscroll_change_callback
, (gpointer
) this );
1560 gtk_widget_show( m_wxwindow
);
1562 if (m_parent
) m_parent
->AddChild( this );
1564 (m_parent
->m_insertCallback
)( m_parent
, this );
1573 wxWindow::~wxWindow()
1577 #if wxUSE_DRAG_AND_DROP
1580 delete m_dropTarget
;
1581 m_dropTarget
= (wxDropTarget
*) NULL
;
1589 m_toolTip
= (wxToolTip
*) NULL
;
1591 #endif // wxUSE_TOOLTIPS
1593 if (m_widget
) Show( FALSE
);
1597 if (m_parent
) m_parent
->RemoveChild( this );
1599 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
1601 if (m_scrollGC
) gdk_gc_unref( m_scrollGC
);
1603 if (m_wxwindow
) gtk_widget_destroy( m_wxwindow
);
1605 if (m_widget
) gtk_widget_destroy( m_widget
);
1607 if (m_cursor
) delete m_cursor
;
1609 DeleteRelatedConstraints();
1612 /* This removes any dangling pointers to this window
1613 * in other windows' constraintsInvolvedIn lists. */
1614 UnsetConstraints(m_constraints
);
1615 delete m_constraints
;
1616 m_constraints
= (wxLayoutConstraints
*) NULL
;
1621 delete m_windowSizer
;
1622 m_windowSizer
= (wxSizer
*) NULL
;
1624 /* If this is a child of a sizer, remove self from parent */
1625 if (m_sizerParent
) m_sizerParent
->RemoveChild((wxWindow
*)this);
1627 /* Just in case the window has been Closed, but
1628 * we're then deleting immediately: don't leave
1629 * dangling pointers. */
1630 wxPendingDelete
.DeleteObject(this);
1632 /* Just in case we've loaded a top-level window via
1633 * wxWindow::LoadNativeDialog but we weren't a dialog
1635 wxTopLevelWindows
.DeleteObject(this);
1637 if (m_windowValidator
) delete m_windowValidator
;
1639 if (m_clientObject
) delete m_clientObject
;
1642 void wxWindow::PreCreation( wxWindow
*parent
, wxWindowID id
,
1643 const wxPoint
&pos
, const wxSize
&size
,
1644 long style
, const wxString
&name
)
1646 wxASSERT_MSG( (!m_needParent
) || (parent
), "Need complete parent." );
1648 m_widget
= (GtkWidget
*) NULL
;
1649 m_wxwindow
= (GtkWidget
*) NULL
;
1652 m_children
.DeleteContents( FALSE
);
1655 if (m_width
== -1) m_width
= 20;
1657 if (m_height
== -1) m_height
= 20;
1662 if (!m_needParent
) /* some reasonable defaults */
1666 m_x
= (gdk_screen_width () - m_width
) / 2;
1667 if (m_x
< 10) m_x
= 10;
1671 m_y
= (gdk_screen_height () - m_height
) / 2;
1672 if (m_y
< 10) m_y
= 10;
1683 m_eventHandler
= this;
1685 m_windowId
= id
== -1 ? wxNewId() : id
;
1689 m_cursor
= new wxCursor( wxCURSOR_ARROW
);
1690 m_font
= *wxSWISS_FONT
;
1691 m_backgroundColour
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
1692 m_foregroundColour
= *wxBLACK
;
1693 m_windowStyle
= style
;
1694 m_windowName
= name
;
1696 m_constraints
= (wxLayoutConstraints
*) NULL
;
1697 m_constraintsInvolvedIn
= (wxList
*) NULL
;
1698 m_windowSizer
= (wxSizer
*) NULL
;
1699 m_sizerParent
= (wxWindow
*) NULL
;
1700 m_autoLayout
= FALSE
;
1702 m_hasScrolling
= FALSE
;
1703 m_isScrolling
= FALSE
;
1704 m_hAdjust
= (GtkAdjustment
*) NULL
;
1705 m_vAdjust
= (GtkAdjustment
*) NULL
;
1706 m_oldHorizontalPos
= 0.0;
1707 m_oldVerticalPos
= 0.0;
1712 #if wxUSE_DRAG_AND_DROP
1713 m_dropTarget
= (wxDropTarget
*) NULL
;
1716 m_windowValidator
= (wxValidator
*) NULL
;
1717 m_scrollGC
= (GdkGC
*) NULL
;
1718 m_widgetStyle
= (GtkStyle
*) NULL
;
1720 m_clientObject
= (wxClientData
*)NULL
;
1721 m_clientData
= NULL
;
1723 m_isStaticBox
= FALSE
;
1726 m_toolTip
= (wxToolTip
*) NULL
;
1727 #endif // wxUSE_TOOLTIPS
1730 void wxWindow::PostCreation()
1732 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1736 /* these get reported to wxWindows -> wxPaintEvent */
1737 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "expose_event",
1738 GTK_SIGNAL_FUNC(gtk_window_expose_callback
), (gpointer
)this );
1740 gtk_signal_connect( GTK_OBJECT(m_wxwindow
), "draw",
1741 GTK_SIGNAL_FUNC(gtk_window_draw_callback
), (gpointer
)this );
1743 /* these are called when the "sunken" or "raised" borders are drawn */
1744 gtk_signal_connect( GTK_OBJECT(m_widget
), "expose_event",
1745 GTK_SIGNAL_FUNC(gtk_window_own_expose_callback
), (gpointer
)this );
1747 gtk_signal_connect( GTK_OBJECT(m_widget
), "draw",
1748 GTK_SIGNAL_FUNC(gtk_window_own_draw_callback
), (gpointer
)this );
1751 ConnectWidget( GetConnectWidget() );
1753 /* we force the creation of wxFrame and wxDialog in the respective code */
1754 if (m_parent
) gtk_widget_realize( m_widget
);
1756 if (m_wxwindow
) gtk_widget_realize( m_wxwindow
);
1758 SetCursor( *wxSTANDARD_CURSOR
);
1763 void wxWindow::ConnectWidget( GtkWidget
*widget
)
1765 gtk_signal_connect( GTK_OBJECT(widget
), "key_press_event",
1766 GTK_SIGNAL_FUNC(gtk_window_key_press_callback
), (gpointer
)this );
1768 gtk_signal_connect( GTK_OBJECT(widget
), "key_release_event",
1769 GTK_SIGNAL_FUNC(gtk_window_key_release_callback
), (gpointer
)this );
1771 gtk_signal_connect( GTK_OBJECT(widget
), "button_press_event",
1772 GTK_SIGNAL_FUNC(gtk_window_button_press_callback
), (gpointer
)this );
1774 gtk_signal_connect( GTK_OBJECT(widget
), "button_release_event",
1775 GTK_SIGNAL_FUNC(gtk_window_button_release_callback
), (gpointer
)this );
1777 gtk_signal_connect( GTK_OBJECT(widget
), "motion_notify_event",
1778 GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback
), (gpointer
)this );
1780 gtk_signal_connect( GTK_OBJECT(widget
), "focus_in_event",
1781 GTK_SIGNAL_FUNC(gtk_window_focus_in_callback
), (gpointer
)this );
1783 gtk_signal_connect( GTK_OBJECT(widget
), "focus_out_event",
1784 GTK_SIGNAL_FUNC(gtk_window_focus_out_callback
), (gpointer
)this );
1786 gtk_signal_connect( GTK_OBJECT(widget
), "enter_notify_event",
1787 GTK_SIGNAL_FUNC(gtk_window_enter_callback
), (gpointer
)this );
1789 gtk_signal_connect( GTK_OBJECT(widget
), "leave_notify_event",
1790 GTK_SIGNAL_FUNC(gtk_window_leave_callback
), (gpointer
)this );
1793 bool wxWindow::HasVMT()
1798 bool wxWindow::Close( bool force
)
1800 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1802 wxCloseEvent
event(wxEVT_CLOSE_WINDOW
, m_windowId
);
1803 event
.SetEventObject(this);
1804 event
.SetCanVeto(!force
);
1806 /* return FALSE if window wasn't closed because the application vetoed the
1808 return GetEventHandler()->ProcessEvent(event
) && !event
.GetVeto();
1811 bool wxWindow::Destroy()
1813 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1820 bool wxWindow::DestroyChildren()
1823 while ((node
= m_children
.First()) != (wxNode
*)NULL
)
1826 if ((child
= (wxWindow
*)node
->Data()) != (wxWindow
*)NULL
)
1829 if (m_children
.Member(child
)) delete node
;
1835 void wxWindow::PrepareDC( wxDC
&WXUNUSED(dc
) )
1837 // are we to set fonts here ?
1840 void wxWindow::DoSetSize( int x
, int y
, int width
, int height
, int sizeFlags
)
1842 wxASSERT_MSG( (m_widget
!= NULL
), "invalid window" );
1843 wxASSERT_MSG( (m_parent
!= NULL
), "wxWindow::SetSize requires parent.\n" );
1845 if (m_resizing
) return; /* I don't like recursions */
1848 if (m_parent
->m_wxwindow
== NULL
) /* i.e. wxNotebook */
1850 /* don't set the size for children of wxNotebook, just take the values. */
1858 int old_width
= m_width
;
1859 int old_height
= m_height
;
1861 if ((sizeFlags
& wxSIZE_USE_EXISTING
) == wxSIZE_USE_EXISTING
)
1863 if (x
!= -1) m_x
= x
;
1864 if (y
!= -1) m_y
= y
;
1865 if (width
!= -1) m_width
= width
;
1866 if (height
!= -1) m_height
= height
;
1876 if ((sizeFlags
& wxSIZE_AUTO_WIDTH
) == wxSIZE_AUTO_WIDTH
)
1878 if (width
== -1) m_width
= 80;
1881 if ((sizeFlags
& wxSIZE_AUTO_HEIGHT
) == wxSIZE_AUTO_HEIGHT
)
1883 if (height
== -1) m_height
= 26;
1886 if ((m_minWidth
!= -1) && (m_width
< m_minWidth
)) m_width
= m_minWidth
;
1887 if ((m_minHeight
!= -1) && (m_height
< m_minHeight
)) m_height
= m_minHeight
;
1888 if ((m_maxWidth
!= -1) && (m_width
> m_maxWidth
)) m_width
= m_maxWidth
;
1889 if ((m_maxHeight
!= -1) && (m_height
> m_maxHeight
)) m_height
= m_maxHeight
;
1891 if (GTK_WIDGET_HAS_DEFAULT(m_widget
))
1893 /* the default button has a border around it */
1896 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
-border
, m_y
-border
);
1898 gtk_widget_set_usize( m_widget
, m_width
+2*border
, m_height
+2*border
);
1902 gtk_myfixed_move( GTK_MYFIXED(m_parent
->m_wxwindow
), m_widget
, m_x
, m_y
);
1904 if ((old_width
!= m_width
) || (old_height
!= m_height
))
1905 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
1911 wxSizeEvent
event( wxSize(m_width
,m_height
), GetId() );
1912 event
.SetEventObject( this );
1913 GetEventHandler()->ProcessEvent( event
);
1918 void wxWindow::OnInternalIdle()
1923 void wxWindow::GetSize( int *width
, int *height
) const
1925 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1927 if (width
) (*width
) = m_width
;
1928 if (height
) (*height
) = m_height
;
1931 void wxWindow::DoSetClientSize( int width
, int height
)
1933 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
1937 SetSize( width
, height
);
1944 if (!m_hasScrolling
)
1946 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
1948 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1949 (m_windowStyle
& wxSUNKEN_BORDER
))
1951 dw
+= 2 * window_class
->xthickness
;
1952 dh
+= 2 * window_class
->ythickness
;
1957 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
1958 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
1960 #if (GTK_MINOR_VERSION == 0)
1961 GtkWidget
*viewport
= scroll_window
->viewport
;
1962 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
1964 if ((m_windowStyle
& wxRAISED_BORDER
) ||
1965 (m_windowStyle
& wxSUNKEN_BORDER
))
1967 dw
+= 2 * viewport_class
->xthickness
;
1968 dh
+= 2 * viewport_class
->ythickness
;
1973 GtkWidget *hscrollbar = scroll_window->hscrollbar;
1974 GtkWidget *vscrollbar = scroll_window->vscrollbar;
1976 we use this instead: range.slider_width = 11 + 2*2pts edge
1979 if (scroll_window
->vscrollbar_visible
)
1981 dw
+= 15; /* dw += vscrollbar->allocation.width; */
1982 dw
+= scroll_class
->scrollbar_spacing
;
1985 if (scroll_window
->hscrollbar_visible
)
1987 dh
+= 15; /* dh += hscrollbar->allocation.height; */
1988 dw
+= scroll_class
->scrollbar_spacing
;
1992 SetSize( width
+dw
, height
+dh
);
1996 void wxWindow::GetClientSize( int *width
, int *height
) const
1998 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2002 if (width
) (*width
) = m_width
;
2003 if (height
) (*height
) = m_height
;
2010 if (!m_hasScrolling
)
2012 GtkStyleClass
*window_class
= m_wxwindow
->style
->klass
;
2014 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2015 (m_windowStyle
& wxSUNKEN_BORDER
))
2017 dw
+= 2 * window_class
->xthickness
;
2018 dh
+= 2 * window_class
->ythickness
;
2023 GtkScrolledWindow
*scroll_window
= GTK_SCROLLED_WINDOW(m_widget
);
2024 GtkScrolledWindowClass
*scroll_class
= GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget
)->klass
);
2026 #if (GTK_MINOR_VERSION == 0)
2027 GtkWidget
*viewport
= scroll_window
->viewport
;
2028 GtkStyleClass
*viewport_class
= viewport
->style
->klass
;
2030 if ((m_windowStyle
& wxRAISED_BORDER
) ||
2031 (m_windowStyle
& wxSUNKEN_BORDER
))
2033 dw
+= 2 * viewport_class
->xthickness
;
2034 dh
+= 2 * viewport_class
->ythickness
;
2038 GtkWidget *hscrollbar = scroll_window->hscrollbar;
2039 GtkWidget *vscrollbar = scroll_window->vscrollbar;
2041 we use this instead: range.slider_width = 11 + 2*2pts edge
2044 if (scroll_window
->vscrollbar_visible
)
2046 dw
+= 15; /* dw += vscrollbar->allocation.width; */
2047 dw
+= scroll_class
->scrollbar_spacing
;
2050 if (scroll_window
->hscrollbar_visible
)
2052 dh
+= 15; /* dh += hscrollbar->allocation.height; */
2053 dh
+= scroll_class
->scrollbar_spacing
;
2057 if (width
) (*width
) = m_width
- dw
;
2058 if (height
) (*height
) = m_height
- dh
;
2062 void wxWindow::GetPosition( int *x
, int *y
) const
2064 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2070 void wxWindow::ClientToScreen( int *x
, int *y
)
2072 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2074 GdkWindow
*source
= (GdkWindow
*) NULL
;
2076 source
= m_wxwindow
->window
;
2078 source
= m_widget
->window
;
2082 gdk_window_get_origin( source
, &org_x
, &org_y
);
2086 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2088 org_x
+= m_widget
->allocation
.x
;
2089 org_y
+= m_widget
->allocation
.y
;
2097 void wxWindow::ScreenToClient( int *x
, int *y
)
2099 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2101 GdkWindow
*source
= (GdkWindow
*) NULL
;
2103 source
= m_wxwindow
->window
;
2105 source
= m_widget
->window
;
2109 gdk_window_get_origin( source
, &org_x
, &org_y
);
2113 if (GTK_WIDGET_NO_WINDOW (m_widget
))
2115 org_x
+= m_widget
->allocation
.x
;
2116 org_y
+= m_widget
->allocation
.y
;
2124 void wxWindow::Centre( int direction
)
2126 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2135 m_parent
->GetSize( &p_w
, &p_h
);
2136 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (p_w
- m_width
) / 2;
2137 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (p_h
- m_height
) / 2;
2141 if (direction
& wxHORIZONTAL
== wxHORIZONTAL
) x
= (gdk_screen_width () - m_width
) / 2;
2142 if (direction
& wxVERTICAL
== wxVERTICAL
) y
= (gdk_screen_height () - m_height
) / 2;
2148 void wxWindow::Fit()
2150 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2154 wxNode
*node
= m_children
.First();
2157 wxWindow
*win
= (wxWindow
*)node
->Data();
2159 win
->GetPosition(&wx
, &wy
);
2160 win
->GetSize(&ww
, &wh
);
2161 if (wx
+ ww
> maxX
) maxX
= wx
+ ww
;
2162 if (wy
+ wh
> maxY
) maxY
= wy
+ wh
;
2164 node
= node
->Next();
2167 SetClientSize(maxX
+ 7, maxY
+ 14);
2170 void wxWindow::SetSizeHints( int minW
, int minH
, int maxW
, int maxH
, int WXUNUSED(incW
), int WXUNUSED(incH
) )
2172 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2180 void wxWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2182 // if (GetAutoLayout()) Layout();
2185 bool wxWindow::Show( bool show
)
2187 wxCHECK_MSG( (m_widget
!= NULL
), FALSE
, "invalid window" );
2189 if (show
== m_isShown
) return TRUE
;
2192 gtk_widget_show( m_widget
);
2194 gtk_widget_hide( m_widget
);
2201 void wxWindow::Enable( bool enable
)
2203 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2205 m_isEnabled
= enable
;
2207 gtk_widget_set_sensitive( m_widget
, enable
);
2208 if (m_wxwindow
) gtk_widget_set_sensitive( m_wxwindow
, enable
);
2211 int wxWindow::GetCharHeight() const
2213 wxCHECK_MSG( (m_widget
!= NULL
), 12, "invalid window" );
2215 wxCHECK_MSG( m_font
.Ok(), 12, "invalid font" );
2217 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2219 return font
->ascent
+ font
->descent
;
2222 int wxWindow::GetCharWidth() const
2224 wxCHECK_MSG( (m_widget
!= NULL
), 8, "invalid window" );
2226 wxCHECK_MSG( m_font
.Ok(), 8, "invalid font" );
2228 GdkFont
*font
= m_font
.GetInternalFont( 1.0 );
2230 return gdk_string_width( font
, "H" );
2233 void wxWindow::GetTextExtent( const wxString
& string
, int *x
, int *y
,
2234 int *descent
, int *externalLeading
, const wxFont
*theFont
, bool WXUNUSED(use16
) ) const
2236 wxFont fontToUse
= m_font
;
2237 if (theFont
) fontToUse
= *theFont
;
2239 wxCHECK_RET( fontToUse
.Ok(), "invalid font" );
2241 GdkFont
*font
= fontToUse
.GetInternalFont( 1.0 );
2242 if (x
) (*x
) = gdk_string_width( font
, string
);
2243 if (y
) (*y
) = font
->ascent
+ font
->descent
;
2244 if (descent
) (*descent
) = font
->descent
;
2245 if (externalLeading
) (*externalLeading
) = 0; // ??
2248 void wxWindow::MakeModal( bool modal
)
2252 // Disable all other windows
2253 if (this->IsKindOf(CLASSINFO(wxDialog
)) || this->IsKindOf(CLASSINFO(wxFrame
)))
2255 wxNode
*node
= wxTopLevelWindows
.First();
2258 wxWindow
*win
= (wxWindow
*)node
->Data();
2259 if (win
!= this) win
->Enable(!modal
);
2261 node
= node
->Next();
2266 void wxWindow::OnKeyDown( wxKeyEvent
&event
)
2268 event
.SetEventType( wxEVT_CHAR
);
2270 if (!GetEventHandler()->ProcessEvent( event
))
2276 void wxWindow::SetFocus()
2278 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2280 GtkWidget
*connect_widget
= GetConnectWidget();
2283 if (GTK_WIDGET_CAN_FOCUS(connect_widget
) /*&& !GTK_WIDGET_HAS_FOCUS (connect_widget)*/ )
2285 gtk_widget_grab_focus (connect_widget
);
2287 else if (GTK_IS_CONTAINER(connect_widget
))
2289 gtk_container_focus( GTK_CONTAINER(connect_widget
), GTK_DIR_TAB_FORWARD
);
2297 wxWindow
*wxWindow::FindFocus()
2299 return g_focusWindow
;
2302 bool wxWindow::AcceptsFocus() const
2304 return IsEnabled() && IsShown() && m_acceptsFocus
;
2307 void wxWindow::AddChild( wxWindow
*child
)
2309 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2310 wxCHECK_RET( (child
!= NULL
), "invalid child" );
2312 m_children
.Append( child
);
2315 wxWindow
*wxWindow::ReParent( wxWindow
*newParent
)
2317 wxCHECK_MSG( (m_widget
!= NULL
), (wxWindow
*) NULL
, "invalid window" );
2319 wxWindow
*oldParent
= GetParent();
2321 if (oldParent
) oldParent
->RemoveChild( this );
2323 gtk_widget_unparent( m_widget
);
2327 newParent
->AddChild( this );
2328 (newParent
->m_insertCallback
)( newParent
, this );
2334 void wxWindow::RemoveChild( wxWindow
*child
)
2336 m_children
.DeleteObject( child
);
2337 child
->m_parent
= (wxWindow
*) NULL
;
2340 void wxWindow::SetReturnCode( int retCode
)
2342 m_retCode
= retCode
;
2345 int wxWindow::GetReturnCode()
2350 void wxWindow::Raise()
2352 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2354 if (m_widget
) gdk_window_raise( m_widget
->window
);
2357 void wxWindow::Lower()
2359 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2361 if (m_widget
) gdk_window_lower( m_widget
->window
);
2364 wxEvtHandler
*wxWindow::GetEventHandler() const
2366 return m_eventHandler
;
2369 void wxWindow::SetEventHandler( wxEvtHandler
*handler
)
2371 m_eventHandler
= handler
;
2374 void wxWindow::PushEventHandler(wxEvtHandler
*handler
)
2376 handler
->SetNextHandler(GetEventHandler());
2377 SetEventHandler(handler
);
2380 wxEvtHandler
*wxWindow::PopEventHandler(bool deleteHandler
)
2382 if (GetEventHandler())
2384 wxEvtHandler
*handlerA
= GetEventHandler();
2385 wxEvtHandler
*handlerB
= handlerA
->GetNextHandler();
2386 handlerA
->SetNextHandler((wxEvtHandler
*) NULL
);
2387 SetEventHandler(handlerB
);
2391 return (wxEvtHandler
*) NULL
;
2397 return (wxEvtHandler
*) NULL
;
2400 wxValidator
*wxWindow::GetValidator()
2402 return m_windowValidator
;
2405 void wxWindow::SetValidator( const wxValidator
& validator
)
2407 if (m_windowValidator
) delete m_windowValidator
;
2408 m_windowValidator
= validator
.Clone();
2409 if (m_windowValidator
) m_windowValidator
->SetWindow(this);
2412 void wxWindow::SetClientObject( wxClientData
*data
)
2414 if (m_clientObject
) delete m_clientObject
;
2415 m_clientObject
= data
;
2418 wxClientData
*wxWindow::GetClientObject()
2420 return m_clientObject
;
2423 void wxWindow::SetClientData( void *data
)
2425 m_clientData
= data
;
2428 void *wxWindow::GetClientData()
2430 return m_clientData
;
2433 bool wxWindow::IsBeingDeleted()
2438 void wxWindow::SetId( wxWindowID id
)
2443 wxWindowID
wxWindow::GetId() const
2448 void wxWindow::SetCursor( const wxCursor
&cursor
)
2450 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2454 if (cursor
== *m_cursor
) return;
2459 *m_cursor
= *wxSTANDARD_CURSOR
;
2462 if ((m_widget
) && (m_widget
->window
))
2463 gdk_window_set_cursor( m_widget
->window
, m_cursor
->GetCursor() );
2465 if ((m_wxwindow
) && (m_wxwindow
->window
))
2466 gdk_window_set_cursor( m_wxwindow
->window
, m_cursor
->GetCursor() );
2469 void wxWindow::WarpPointer( int WXUNUSED(x
), int WXUNUSED(y
) )
2474 void wxWindow::Refresh( bool eraseBackground
, const wxRect
*rect
)
2476 wxCHECK_RET( (m_widget
!= NULL
), "invalid window" );
2478 if (eraseBackground
&& m_wxwindow
&& m_wxwindow
->window
)
2482 gdk_window_clear_area( m_wxwindow
->window
,
2484 rect
->width
, rect
->height
);
2488 gdk_window_clear( m_wxwindow
->window
);
2495 gtk_widget_draw( m_wxwindow
, (GdkRectangle
*) NULL
);
2497 gtk_widget_draw( m_widget
, (GdkRectangle
*) NULL
);
2501 GdkRectangle gdk_rect
;
2502 gdk_rect
.x
= rect
->x
;
2503 gdk_rect
.y
= rect
->y
;
2504 gdk_rect
.width
= rect
->width
;
2505 gdk_rect
.height
= rect
->height
;
2508 gtk_widget_draw( m_wxwindow
, &gdk_rect
);
2510 gtk_widget_draw( m_widget
, &gdk_rect
);
2514 wxRegion
wxWindow::GetUpdateRegion() const
2516 return m_updateRegion
;
2519 bool wxWindow::IsExposed( int x
, int y
) const
2521 return (m_updateRegion
.Contains( x
, y
) != wxOutRegion
);
2524 bool wxWindow::IsExposed( int x
, int y
, int w
, int h
) const
2526 return (m_updateRegion
.Contains( x
, y
, w
, h
) != wxOutRegion
);
2529 bool wxWindow::IsExposed( const wxPoint
& pt
) const
2531 return (m_updateRegion
.Contains( pt
.x
, pt
.y
) != wxOutRegion
);
2534 bool wxWindow::IsExposed( const wxRect
& rect
) const
2536 return (m_updateRegion
.Contains( rect
.x
, rect
.y
, rect
.width
, rect
.height
) != wxOutRegion
);
2539 void wxWindow::Clear()
2541 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2543 if (m_wxwindow
&& m_wxwindow
->window
)
2545 gdk_window_clear( m_wxwindow
->window
);
2550 void wxWindow::SetToolTip( const wxString
&tip
)
2554 m_toolTip
->SetTip( tip
);
2558 SetToolTip( new wxToolTip( tip
) );
2561 // setting empty tooltip text does not remove the tooltip any more for
2562 // wxMSW compatibility - use SetToolTip((wxToolTip *)NULL) for this
2565 void wxWindow::SetToolTip( wxToolTip
*tip
)
2569 m_toolTip
->SetTip( (char*) NULL
);
2576 m_toolTip
->Apply( this );
2579 void wxWindow::ApplyToolTip( GtkTooltips
*tips
, const char *tip
)
2581 gtk_tooltips_set_tip( tips
, GetConnectWidget(), tip
, (gchar
*) NULL
);
2583 #endif // wxUSE_TOOLTIPS
2585 wxColour
wxWindow::GetBackgroundColour() const
2587 return m_backgroundColour
;
2590 void wxWindow::SetBackgroundColour( const wxColour
&colour
)
2592 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2594 if (m_backgroundColour
== colour
) return;
2596 m_backgroundColour
= colour
;
2597 if (!m_backgroundColour
.Ok()) return;
2599 if (m_wxwindow
&& m_wxwindow
->window
)
2601 /* wxMSW doesn't clear the window here. I don't do that
2602 either to provide compatibility. call Clear() to do
2605 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_wxwindow
->window
) );
2606 gdk_window_set_background( m_wxwindow
->window
, m_backgroundColour
.GetColor() );
2609 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2611 if (sysbg
.Red() == colour
.Red() &&
2612 sysbg
.Green() == colour
.Green() &&
2613 sysbg
.Blue() == colour
.Blue())
2615 m_backgroundColour
= wxNullColour
;
2617 m_backgroundColour
= sysbg
;
2625 wxColour
wxWindow::GetForegroundColour() const
2627 return m_foregroundColour
;
2630 void wxWindow::SetForegroundColour( const wxColour
&colour
)
2632 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2634 if (m_foregroundColour
== colour
) return;
2636 m_foregroundColour
= colour
;
2637 if (!m_foregroundColour
.Ok()) return;
2639 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2640 if (sysbg
.Red() == colour
.Red() &&
2641 sysbg
.Green() == colour
.Green() &&
2642 sysbg
.Blue() == colour
.Blue())
2644 m_backgroundColour
= wxNullColour
;
2646 m_backgroundColour
= sysbg
;
2654 GtkStyle
*wxWindow::GetWidgetStyle()
2656 if (m_widgetStyle
) gtk_style_unref( m_widgetStyle
);
2660 gtk_widget_get_style( m_widget
) );
2662 return m_widgetStyle
;
2665 void wxWindow::SetWidgetStyle()
2667 GtkStyle
*style
= GetWidgetStyle();
2669 gdk_font_unref( style
->font
);
2670 style
->font
= gdk_font_ref( m_font
.GetInternalFont( 1.0 ) );
2672 if (m_foregroundColour
.Ok())
2674 m_foregroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2675 style
->fg
[GTK_STATE_NORMAL
] = *m_foregroundColour
.GetColor();
2676 style
->fg
[GTK_STATE_PRELIGHT
] = *m_foregroundColour
.GetColor();
2677 style
->fg
[GTK_STATE_ACTIVE
] = *m_foregroundColour
.GetColor();
2680 if (m_backgroundColour
.Ok())
2682 m_backgroundColour
.CalcPixel( gdk_window_get_colormap( m_widget
->window
) );
2683 style
->bg
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2684 style
->base
[GTK_STATE_NORMAL
] = *m_backgroundColour
.GetColor();
2685 style
->bg
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2686 style
->base
[GTK_STATE_PRELIGHT
] = *m_backgroundColour
.GetColor();
2687 style
->bg
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2688 style
->base
[GTK_STATE_ACTIVE
] = *m_backgroundColour
.GetColor();
2689 style
->bg
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2690 style
->base
[GTK_STATE_INSENSITIVE
] = *m_backgroundColour
.GetColor();
2694 void wxWindow::ApplyWidgetStyle()
2698 bool wxWindow::Validate()
2700 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2702 wxNode
*node
= m_children
.First();
2705 wxWindow
*child
= (wxWindow
*)node
->Data();
2706 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->Validate(this))
2710 node
= node
->Next();
2715 bool wxWindow::TransferDataToWindow()
2717 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2719 wxNode
*node
= m_children
.First();
2722 wxWindow
*child
= (wxWindow
*)node
->Data();
2723 if (child
->GetValidator() && /* child->GetValidator()->Ok() && */
2724 !child
->GetValidator()->TransferToWindow() )
2726 wxMessageBox( _("Application Error"), _("Could not transfer data to window"), wxOK
|wxICON_EXCLAMATION
);
2729 node
= node
->Next();
2734 bool wxWindow::TransferDataFromWindow()
2736 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2738 wxNode
*node
= m_children
.First();
2741 wxWindow
*child
= (wxWindow
*)node
->Data();
2742 if ( child
->GetValidator() && /* child->GetValidator()->Ok() && */ !child
->GetValidator()->TransferFromWindow() )
2746 node
= node
->Next();
2751 void wxWindow::SetAcceleratorTable( const wxAcceleratorTable
& accel
)
2753 m_acceleratorTable
= accel
;
2756 void wxWindow::OnInitDialog( wxInitDialogEvent
&WXUNUSED(event
) )
2758 TransferDataToWindow();
2761 void wxWindow::InitDialog()
2763 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2765 wxInitDialogEvent
event(GetId());
2766 event
.SetEventObject( this );
2767 GetEventHandler()->ProcessEvent(event
);
2770 static void SetInvokingWindow( wxMenu
*menu
, wxWindow
*win
)
2772 menu
->SetInvokingWindow( win
);
2773 wxNode
*node
= menu
->GetItems().First();
2776 wxMenuItem
*menuitem
= (wxMenuItem
*)node
->Data();
2777 if (menuitem
->IsSubMenu())
2779 SetInvokingWindow( menuitem
->GetSubMenu(), win
);
2781 node
= node
->Next();
2785 static gint gs_pop_x
= 0;
2786 static gint gs_pop_y
= 0;
2788 static void pop_pos_callback( GtkMenu
*menu
, gint
*x
, gint
*y
, wxWindow
*win
)
2790 win
->ClientToScreen( &gs_pop_x
, &gs_pop_y
);
2795 bool wxWindow::PopupMenu( wxMenu
*menu
, int x
, int y
)
2797 wxCHECK_MSG( m_widget
!= NULL
, FALSE
, "invalid window" );
2799 wxCHECK_MSG( menu
!= NULL
, FALSE
, "invalid popup-menu" );
2801 SetInvokingWindow( menu
, this );
2809 GTK_MENU(menu
->m_menu
),
2810 (GtkWidget
*) NULL
, // parent menu shell
2811 (GtkWidget
*) NULL
, // parent menu item
2812 (GtkMenuPositionFunc
) pop_pos_callback
,
2813 (gpointer
) this, // client data
2814 0, // button used to activate it
2815 0 //gs_timeLastClick // the time of activation
2820 #if wxUSE_DRAG_AND_DROP
2822 void wxWindow::SetDropTarget( wxDropTarget
*dropTarget
)
2824 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2826 GtkWidget
*dnd_widget
= GetConnectWidget();
2828 if (m_dropTarget
) m_dropTarget
->UnregisterWidget( dnd_widget
);
2830 if (m_dropTarget
) delete m_dropTarget
;
2831 m_dropTarget
= dropTarget
;
2833 if (m_dropTarget
) m_dropTarget
->RegisterWidget( dnd_widget
);
2836 wxDropTarget
*wxWindow::GetDropTarget() const
2838 return m_dropTarget
;
2843 GtkWidget
* wxWindow::GetConnectWidget()
2845 GtkWidget
*connect_widget
= m_widget
;
2846 if (m_wxwindow
) connect_widget
= m_wxwindow
;
2848 return connect_widget
;
2851 bool wxWindow::IsOwnGtkWindow( GdkWindow
*window
)
2853 if (m_wxwindow
) return (window
== m_wxwindow
->window
);
2854 return (window
== m_widget
->window
);
2857 void wxWindow::SetFont( const wxFont
&font
)
2859 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2861 if (m_font
== font
) return;
2863 if (((wxFont
*)&font
)->Ok())
2866 m_font
= *wxSWISS_FONT
;
2868 wxColour sysbg
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
);
2869 if (sysbg
.Red() == m_backgroundColour
.Red() &&
2870 sysbg
.Green() == m_backgroundColour
.Green() &&
2871 sysbg
.Blue() == m_backgroundColour
.Blue())
2873 m_backgroundColour
= wxNullColour
;
2875 m_backgroundColour
= sysbg
;
2883 void wxWindow::SetWindowStyleFlag( long flag
)
2885 m_windowStyle
= flag
;
2888 long wxWindow::GetWindowStyleFlag() const
2890 return m_windowStyle
;
2893 void wxWindow::CaptureMouse()
2895 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2897 wxCHECK_RET( g_capturing
== FALSE
, "CaptureMouse called twice" );
2899 GtkWidget
*connect_widget
= GetConnectWidget();
2900 gtk_grab_add( connect_widget
);
2901 gdk_pointer_grab( connect_widget
->window
, FALSE
,
2903 (GDK_BUTTON_PRESS_MASK
|
2904 GDK_BUTTON_RELEASE_MASK
|
2905 GDK_POINTER_MOTION_MASK
),
2912 void wxWindow::ReleaseMouse()
2914 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2916 wxCHECK_RET( g_capturing
== TRUE
, "ReleaseMouse called twice" );
2918 GtkWidget
*connect_widget
= GetConnectWidget();
2919 gtk_grab_remove( connect_widget
);
2920 gdk_pointer_ungrab ( GDK_CURRENT_TIME
);
2921 g_capturing
= FALSE
;
2924 void wxWindow::SetTitle( const wxString
&WXUNUSED(title
) )
2928 wxString
wxWindow::GetTitle() const
2930 return (wxString
&)m_windowName
;
2933 wxString
wxWindow::GetLabel() const
2938 void wxWindow::SetName( const wxString
&name
)
2940 m_windowName
= name
;
2943 wxString
wxWindow::GetName() const
2945 return (wxString
&)m_windowName
;
2948 bool wxWindow::IsShown() const
2953 bool wxWindow::IsRetained()
2958 wxWindow
*wxWindow::FindWindow( long id
)
2960 if (id
== m_windowId
) return this;
2961 wxNode
*node
= m_children
.First();
2964 wxWindow
*child
= (wxWindow
*)node
->Data();
2965 wxWindow
*res
= child
->FindWindow( id
);
2966 if (res
) return res
;
2967 node
= node
->Next();
2969 return (wxWindow
*) NULL
;
2972 wxWindow
*wxWindow::FindWindow( const wxString
& name
)
2974 if (name
== m_windowName
) return this;
2975 wxNode
*node
= m_children
.First();
2978 wxWindow
*child
= (wxWindow
*)node
->Data();
2979 wxWindow
*res
= child
->FindWindow( name
);
2980 if (res
) return res
;
2981 node
= node
->Next();
2983 return (wxWindow
*) NULL
;
2986 void wxWindow::SetScrollbar( int orient
, int pos
, int thumbVisible
,
2987 int range
, bool refresh
)
2989 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
2991 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
2993 m_hasScrolling
= TRUE
;
2995 if (orient
== wxHORIZONTAL
)
2997 float fpos
= (float)pos
;
2998 float frange
= (float)range
;
2999 float fthumb
= (float)thumbVisible
;
3000 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3001 if (fpos
< 0.0) fpos
= 0.0;
3003 if ((fabs(frange
-m_hAdjust
->upper
) < 0.2) &&
3004 (fabs(fthumb
-m_hAdjust
->page_size
) < 0.2))
3006 SetScrollPos( orient
, pos
, refresh
);
3010 m_oldHorizontalPos
= fpos
;
3012 m_hAdjust
->lower
= 0.0;
3013 m_hAdjust
->upper
= frange
;
3014 m_hAdjust
->value
= fpos
;
3015 m_hAdjust
->step_increment
= 1.0;
3016 m_hAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3017 m_hAdjust
->page_size
= fthumb
;
3021 float fpos
= (float)pos
;
3022 float frange
= (float)range
;
3023 float fthumb
= (float)thumbVisible
;
3024 if (fpos
> frange
-fthumb
) fpos
= frange
-fthumb
;
3025 if (fpos
< 0.0) fpos
= 0.0;
3027 if ((fabs(frange
-m_vAdjust
->upper
) < 0.2) &&
3028 (fabs(fthumb
-m_vAdjust
->page_size
) < 0.2))
3030 SetScrollPos( orient
, pos
, refresh
);
3034 m_oldVerticalPos
= fpos
;
3036 m_vAdjust
->lower
= 0.0;
3037 m_vAdjust
->upper
= frange
;
3038 m_vAdjust
->value
= fpos
;
3039 m_vAdjust
->step_increment
= 1.0;
3040 m_vAdjust
->page_increment
= (float)(wxMax(fthumb
,0));
3041 m_vAdjust
->page_size
= fthumb
;
3044 if (m_wxwindow
->window
)
3046 if (orient
== wxHORIZONTAL
)
3047 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "changed" );
3049 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "changed" );
3051 gtk_widget_set_usize( m_widget
, m_width
, m_height
);
3055 void wxWindow::SetScrollPos( int orient
, int pos
, bool WXUNUSED(refresh
) )
3057 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3059 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3061 if (orient
== wxHORIZONTAL
)
3063 float fpos
= (float)pos
;
3064 if (fpos
> m_hAdjust
->upper
- m_hAdjust
->page_size
) fpos
= m_hAdjust
->upper
- m_hAdjust
->page_size
;
3065 if (fpos
< 0.0) fpos
= 0.0;
3066 m_oldHorizontalPos
= fpos
;
3068 if (fabs(fpos
-m_hAdjust
->value
) < 0.2) return;
3069 m_hAdjust
->value
= fpos
;
3073 float fpos
= (float)pos
;
3074 if (fpos
> m_vAdjust
->upper
- m_vAdjust
->page_size
) fpos
= m_vAdjust
->upper
- m_vAdjust
->page_size
;
3075 if (fpos
< 0.0) fpos
= 0.0;
3076 m_oldVerticalPos
= fpos
;
3078 if (fabs(fpos
-m_vAdjust
->value
) < 0.2) return;
3079 m_vAdjust
->value
= fpos
;
3084 if (m_wxwindow
->window
)
3086 if (orient
== wxHORIZONTAL
)
3087 gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust
), "value_changed" );
3089 gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust
), "value_changed" );
3094 int wxWindow::GetScrollThumb( int orient
) const
3096 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3098 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3100 if (orient
== wxHORIZONTAL
)
3101 return (int)(m_hAdjust
->page_size
+0.5);
3103 return (int)(m_vAdjust
->page_size
+0.5);
3106 int wxWindow::GetScrollPos( int orient
) const
3108 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3110 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3112 if (orient
== wxHORIZONTAL
)
3113 return (int)(m_hAdjust
->value
+0.5);
3115 return (int)(m_vAdjust
->value
+0.5);
3118 int wxWindow::GetScrollRange( int orient
) const
3120 wxCHECK_MSG( m_widget
!= NULL
, 0, "invalid window" );
3122 wxCHECK_MSG( m_wxwindow
!= NULL
, 0, "window needs client area for scrolling" );
3124 if (orient
== wxHORIZONTAL
)
3125 return (int)(m_hAdjust
->upper
+0.5);
3127 return (int)(m_vAdjust
->upper
+0.5);
3130 void wxWindow::ScrollWindow( int dx
, int dy
, const wxRect
* WXUNUSED(rect
) )
3132 wxCHECK_RET( m_widget
!= NULL
, "invalid window" );
3134 wxCHECK_RET( m_wxwindow
!= NULL
, "window needs client area for scrolling" );
3136 wxNode
*node
= m_children
.First();
3139 wxWindow
*child
= (wxWindow
*) node
->Data();
3140 child
->Move( child
->m_x
+ dx
, child
->m_y
+ dy
);
3141 node
= node
->Next();
3146 GetClientSize( &cw
, &ch
);
3148 int w
= cw
- abs(dx
);
3149 int h
= ch
- abs(dy
);
3150 if ((h
< 0) || (w
< 0))
3157 if (dx
< 0) s_x
= -dx
;
3158 if (dy
< 0) s_y
= -dy
;
3161 if (dx
> 0) d_x
= dx
;
3162 if (dy
> 0) d_y
= dy
;
3166 m_scrollGC
= gdk_gc_new( m_wxwindow
->window
);
3167 gdk_gc_set_exposures( m_scrollGC
, TRUE
);
3170 gdk_window_copy_area( m_wxwindow
->window
, m_scrollGC
, d_x
, d_y
,
3171 m_wxwindow
->window
, s_x
, s_y
, w
, h
);
3174 if (dx
< 0) rect
.x
= cw
+dx
; else rect
.x
= 0;
3175 if (dy
< 0) rect
.y
= ch
+dy
; else rect
.y
= 0;
3176 if (dy
!= 0) rect
.width
= cw
; else rect
.width
= abs(dx
);
3177 if (dx
!= 0) rect
.height
= ch
; else rect
.height
= abs(dy
);
3179 Refresh( TRUE
, &rect
);
3182 //-------------------------------------------------------------------------------------
3184 //-------------------------------------------------------------------------------------
3186 wxLayoutConstraints
*wxWindow::GetConstraints() const
3188 return m_constraints
;
3191 void wxWindow::SetConstraints( wxLayoutConstraints
*constraints
)
3195 UnsetConstraints(m_constraints
);
3196 delete m_constraints
;
3198 m_constraints
= constraints
;
3201 // Make sure other windows know they're part of a 'meaningful relationship'
3202 if (m_constraints
->left
.GetOtherWindow() && (m_constraints
->left
.GetOtherWindow() != this))
3203 m_constraints
->left
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3204 if (m_constraints
->top
.GetOtherWindow() && (m_constraints
->top
.GetOtherWindow() != this))
3205 m_constraints
->top
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3206 if (m_constraints
->right
.GetOtherWindow() && (m_constraints
->right
.GetOtherWindow() != this))
3207 m_constraints
->right
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3208 if (m_constraints
->bottom
.GetOtherWindow() && (m_constraints
->bottom
.GetOtherWindow() != this))
3209 m_constraints
->bottom
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3210 if (m_constraints
->width
.GetOtherWindow() && (m_constraints
->width
.GetOtherWindow() != this))
3211 m_constraints
->width
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3212 if (m_constraints
->height
.GetOtherWindow() && (m_constraints
->height
.GetOtherWindow() != this))
3213 m_constraints
->height
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3214 if (m_constraints
->centreX
.GetOtherWindow() && (m_constraints
->centreX
.GetOtherWindow() != this))
3215 m_constraints
->centreX
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3216 if (m_constraints
->centreY
.GetOtherWindow() && (m_constraints
->centreY
.GetOtherWindow() != this))
3217 m_constraints
->centreY
.GetOtherWindow()->AddConstraintReference((wxWindow
*)this);
3223 void wxWindow::SetAutoLayout( bool autoLayout
)
3225 m_autoLayout
= autoLayout
;
3228 bool wxWindow::GetAutoLayout() const
3230 return m_autoLayout
;
3233 wxSizer
*wxWindow::GetSizer() const
3235 return m_windowSizer
;
3238 void wxWindow::SetSizerParent( wxWindow
*win
)
3240 m_sizerParent
= win
;
3243 wxWindow
*wxWindow::GetSizerParent() const
3245 return m_sizerParent
;
3248 // This removes any dangling pointers to this window
3249 // in other windows' constraintsInvolvedIn lists.
3250 void wxWindow::UnsetConstraints(wxLayoutConstraints
*c
)
3254 if (c
->left
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3255 c
->left
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3256 if (c
->top
.GetOtherWindow() && (c
->top
.GetOtherWindow() != this))
3257 c
->top
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3258 if (c
->right
.GetOtherWindow() && (c
->right
.GetOtherWindow() != this))
3259 c
->right
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3260 if (c
->bottom
.GetOtherWindow() && (c
->bottom
.GetOtherWindow() != this))
3261 c
->bottom
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3262 if (c
->width
.GetOtherWindow() && (c
->width
.GetOtherWindow() != this))
3263 c
->width
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3264 if (c
->height
.GetOtherWindow() && (c
->height
.GetOtherWindow() != this))
3265 c
->height
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3266 if (c
->centreX
.GetOtherWindow() && (c
->centreX
.GetOtherWindow() != this))
3267 c
->centreX
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3268 if (c
->centreY
.GetOtherWindow() && (c
->centreY
.GetOtherWindow() != this))
3269 c
->centreY
.GetOtherWindow()->RemoveConstraintReference((wxWindow
*)this);
3273 // Back-pointer to other windows we're involved with, so if we delete
3274 // this window, we must delete any constraints we're involved with.
3275 void wxWindow::AddConstraintReference(wxWindow
*otherWin
)
3277 if (!m_constraintsInvolvedIn
)
3278 m_constraintsInvolvedIn
= new wxList
;
3279 if (!m_constraintsInvolvedIn
->Member(otherWin
))
3280 m_constraintsInvolvedIn
->Append(otherWin
);
3283 // REMOVE back-pointer to other windows we're involved with.
3284 void wxWindow::RemoveConstraintReference(wxWindow
*otherWin
)
3286 if (m_constraintsInvolvedIn
)
3287 m_constraintsInvolvedIn
->DeleteObject(otherWin
);
3290 // Reset any constraints that mention this window
3291 void wxWindow::DeleteRelatedConstraints()
3293 if (m_constraintsInvolvedIn
)
3295 wxNode
*node
= m_constraintsInvolvedIn
->First();
3298 wxWindow
*win
= (wxWindow
*)node
->Data();
3299 wxNode
*next
= node
->Next();
3300 wxLayoutConstraints
*constr
= win
->GetConstraints();
3302 // Reset any constraints involving this window
3305 constr
->left
.ResetIfWin((wxWindow
*)this);
3306 constr
->top
.ResetIfWin((wxWindow
*)this);
3307 constr
->right
.ResetIfWin((wxWindow
*)this);
3308 constr
->bottom
.ResetIfWin((wxWindow
*)this);
3309 constr
->width
.ResetIfWin((wxWindow
*)this);
3310 constr
->height
.ResetIfWin((wxWindow
*)this);
3311 constr
->centreX
.ResetIfWin((wxWindow
*)this);
3312 constr
->centreY
.ResetIfWin((wxWindow
*)this);
3317 delete m_constraintsInvolvedIn
;
3318 m_constraintsInvolvedIn
= (wxList
*) NULL
;
3322 void wxWindow::SetSizer(wxSizer
*sizer
)
3324 m_windowSizer
= sizer
;
3326 sizer
->SetSizerParent((wxWindow
*)this);
3333 bool wxWindow::Layout()
3335 if (GetConstraints())
3338 GetClientSize(&w
, &h
);
3339 GetConstraints()->width
.SetValue(w
);
3340 GetConstraints()->height
.SetValue(h
);
3343 // If top level (one sizer), evaluate the sizer's constraints.
3347 GetSizer()->ResetConstraints(); // Mark all constraints as unevaluated
3348 GetSizer()->LayoutPhase1(&noChanges
);
3349 GetSizer()->LayoutPhase2(&noChanges
);
3350 GetSizer()->SetConstraintSizes(); // Recursively set the real window sizes
3355 // Otherwise, evaluate child constraints
3356 ResetConstraints(); // Mark all constraints as unevaluated
3357 DoPhase(1); // Just one phase need if no sizers involved
3359 SetConstraintSizes(); // Recursively set the real window sizes
3365 // Do a phase of evaluating constraints:
3366 // the default behaviour. wxSizers may do a similar
3367 // thing, but also impose their own 'constraints'
3368 // and order the evaluation differently.
3369 bool wxWindow::LayoutPhase1(int *noChanges
)
3371 wxLayoutConstraints
*constr
= GetConstraints();
3374 return constr
->SatisfyConstraints((wxWindow
*)this, noChanges
);
3380 bool wxWindow::LayoutPhase2(int *noChanges
)
3390 // Do a phase of evaluating child constraints
3391 bool wxWindow::DoPhase(int phase
)
3393 int noIterations
= 0;
3394 int maxIterations
= 500;
3398 while ((noChanges
> 0) && (noIterations
< maxIterations
))
3402 wxNode
*node
= m_children
.First();
3405 wxWindow
*child
= (wxWindow
*)node
->Data();
3406 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) && !child
->IsKindOf(CLASSINFO(wxDialog
)))
3408 wxLayoutConstraints
*constr
= child
->GetConstraints();
3411 if (succeeded
.Member(child
))
3416 int tempNoChanges
= 0;
3417 bool success
= ( (phase
== 1) ? child
->LayoutPhase1(&tempNoChanges
) : child
->LayoutPhase2(&tempNoChanges
) ) ;
3418 noChanges
+= tempNoChanges
;
3421 succeeded
.Append(child
);
3426 node
= node
->Next();
3433 void wxWindow::ResetConstraints()
3435 wxLayoutConstraints
*constr
= GetConstraints();
3438 constr
->left
.SetDone(FALSE
);
3439 constr
->top
.SetDone(FALSE
);
3440 constr
->right
.SetDone(FALSE
);
3441 constr
->bottom
.SetDone(FALSE
);
3442 constr
->width
.SetDone(FALSE
);
3443 constr
->height
.SetDone(FALSE
);
3444 constr
->centreX
.SetDone(FALSE
);
3445 constr
->centreY
.SetDone(FALSE
);
3447 wxNode
*node
= m_children
.First();
3450 wxWindow
*win
= (wxWindow
*)node
->Data();
3451 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3452 win
->ResetConstraints();
3453 node
= node
->Next();
3457 // Need to distinguish between setting the 'fake' size for
3458 // windows and sizers, and setting the real values.
3459 void wxWindow::SetConstraintSizes(bool recurse
)
3461 wxLayoutConstraints
*constr
= GetConstraints();
3462 if (constr
&& constr
->left
.GetDone() && constr
->right
.GetDone() &&
3463 constr
->width
.GetDone() && constr
->height
.GetDone())
3465 int x
= constr
->left
.GetValue();
3466 int y
= constr
->top
.GetValue();
3467 int w
= constr
->width
.GetValue();
3468 int h
= constr
->height
.GetValue();
3470 // If we don't want to resize this window, just move it...
3471 if ((constr
->width
.GetRelationship() != wxAsIs
) ||
3472 (constr
->height
.GetRelationship() != wxAsIs
))
3474 // Calls Layout() recursively. AAAGH. How can we stop that.
3475 // Simply take Layout() out of non-top level OnSizes.
3476 SizerSetSize(x
, y
, w
, h
);
3485 char *windowClass
= this->GetClassInfo()->GetClassName();
3488 if (GetName() == "")
3489 winName
= "unnamed";
3491 winName
= GetName();
3492 wxLogDebug( "Constraint(s) not satisfied for window of type %s, name %s:\n",
3493 (const char *)windowClass
,
3494 (const char *)winName
);
3495 if (!constr
->left
.GetDone()) wxLogDebug( " unsatisfied 'left' constraint.\n" );
3496 if (!constr
->right
.GetDone()) wxLogDebug( " unsatisfied 'right' constraint.\n" );
3497 if (!constr
->width
.GetDone()) wxLogDebug( " unsatisfied 'width' constraint.\n" );
3498 if (!constr
->height
.GetDone()) wxLogDebug( " unsatisfied 'height' constraint.\n" );
3499 wxLogDebug( "Please check constraints: try adding AsIs() constraints.\n" );
3504 wxNode
*node
= m_children
.First();
3507 wxWindow
*win
= (wxWindow
*)node
->Data();
3508 if (!win
->IsKindOf(CLASSINFO(wxFrame
)) && !win
->IsKindOf(CLASSINFO(wxDialog
)))
3509 win
->SetConstraintSizes();
3510 node
= node
->Next();
3515 // This assumes that all sizers are 'on' the same
3516 // window, i.e. the parent of this window.
3517 void wxWindow::TransformSizerToActual(int *x
, int *y
) const
3519 if (!m_sizerParent
|| m_sizerParent
->IsKindOf(CLASSINFO(wxDialog
)) ||
3520 m_sizerParent
->IsKindOf(CLASSINFO(wxFrame
)) )
3524 m_sizerParent
->GetPosition(&xp
, &yp
);
3525 m_sizerParent
->TransformSizerToActual(&xp
, &yp
);
3530 void wxWindow::SizerSetSize(int x
, int y
, int w
, int h
)
3534 TransformSizerToActual(&xx
, &yy
);
3535 SetSize(xx
, yy
, w
, h
);
3538 void wxWindow::SizerMove(int x
, int y
)
3542 TransformSizerToActual(&xx
, &yy
);
3546 // Only set the size/position of the constraint (if any)
3547 void wxWindow::SetSizeConstraint(int x
, int y
, int w
, int h
)
3549 wxLayoutConstraints
*constr
= GetConstraints();
3554 constr
->left
.SetValue(x
);
3555 constr
->left
.SetDone(TRUE
);
3559 constr
->top
.SetValue(y
);
3560 constr
->top
.SetDone(TRUE
);
3564 constr
->width
.SetValue(w
);
3565 constr
->width
.SetDone(TRUE
);
3569 constr
->height
.SetValue(h
);
3570 constr
->height
.SetDone(TRUE
);
3575 void wxWindow::MoveConstraint(int x
, int y
)
3577 wxLayoutConstraints
*constr
= GetConstraints();
3582 constr
->left
.SetValue(x
);
3583 constr
->left
.SetDone(TRUE
);
3587 constr
->top
.SetValue(y
);
3588 constr
->top
.SetDone(TRUE
);
3593 void wxWindow::GetSizeConstraint(int *w
, int *h
) const
3595 wxLayoutConstraints
*constr
= GetConstraints();
3598 *w
= constr
->width
.GetValue();
3599 *h
= constr
->height
.GetValue();
3605 void wxWindow::GetClientSizeConstraint(int *w
, int *h
) const
3607 wxLayoutConstraints
*constr
= GetConstraints();
3610 *w
= constr
->width
.GetValue();
3611 *h
= constr
->height
.GetValue();
3614 GetClientSize(w
, h
);
3617 void wxWindow::GetPositionConstraint(int *x
, int *y
) const
3619 wxLayoutConstraints
*constr
= GetConstraints();
3622 *x
= constr
->left
.GetValue();
3623 *y
= constr
->top
.GetValue();