]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/window.cpp
Rewrote wxRadioBox (recompile)
[wxWidgets.git] / src / gtk1 / window.cpp
index 8159b280a241216f4e599f8b15eb50d439508b2f..eec08efb5b81f040a63ceff1767e522ee24e7f9e 100644 (file)
 #include "wx/menu.h"
 #include "wx/notebook.h"
 #include "wx/statusbr.h"
-#include <wx/intl.h>
-#include "gdk/gdkkeysyms.h"
-#include <math.h>
+#include "wx/intl.h"
 #include "wx/gtk/win_gtk.h"
 #include "gdk/gdkprivate.h"
+#include "gdk/gdkkeysyms.h"
+
+#include <math.h>
 
 //-----------------------------------------------------------------------------
 // documentation on internals
 extern wxList wxPendingDelete;
 extern wxList wxTopLevelWindows;
 extern bool   g_blockEventsOnDrag;
+       bool   g_capturing = FALSE;
 
 //-----------------------------------------------------------------------------
 // "expose_event" (of m_wxwindow, not of m_widget)
@@ -317,7 +319,7 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
   }
     
   if (!win->HasVMT()) return TRUE;
-    
+
 /*
   printf( "OnButtonPress from " );
   if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
@@ -370,21 +372,24 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
   // Some control don't have their own X window and thus cannot get
   // any events. 
   
-  wxNode *node = win->GetChildren()->First();
-  while (node)
+  if (!g_capturing)
   {
-    wxWindow *child = (wxWindow*)node->Data();
-    if ((child->m_x <= event.m_x) &&
-        (child->m_y <= event.m_y) &&
-       (child->m_x+child->m_width  >= event.m_x) &&
-       (child->m_y+child->m_height >= event.m_y))
+    wxNode *node = win->GetChildren()->First();
+    while (node)
     {
-      win = child;
-      event.m_x -= child->m_x;
-      event.m_y -= child->m_y;
-      break;
+      wxWindow *child = (wxWindow*)node->Data();
+      if ((child->m_x <= event.m_x) &&
+          (child->m_y <= event.m_y) &&
+         (child->m_x+child->m_width  >= event.m_x) &&
+         (child->m_y+child->m_height >= event.m_y))
+      {
+        win = child;
+        event.m_x -= child->m_x;
+        event.m_y -= child->m_y;
+        break;
+      }
+      node = node->Next();
     }
-    node = node->Next();
   }
   
   event.SetEventObject( win );
@@ -396,12 +401,13 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
 }
 
 //-----------------------------------------------------------------------------
-// "button_release"
+// "button_release_event"
 //-----------------------------------------------------------------------------
 
 static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
 { 
   if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
+  
   if (g_blockEventsOnDrag) return TRUE;
 
   if (!win->HasVMT()) return TRUE;
@@ -436,21 +442,24 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
   // Some control don't have their own X window and thus cannot get
   // any events. 
   
-  wxNode *node = win->GetChildren()->First();
-  while (node)
+  if (!g_capturing)
   {
-    wxWindow *child = (wxWindow*)node->Data();
-    if ((child->m_x <= event.m_x) &&
-        (child->m_y <= event.m_y) &&
-       (child->m_x+child->m_width  >= event.m_x) &&
-       (child->m_y+child->m_height >= event.m_y))
+    wxNode *node = win->GetChildren()->First();
+    while (node)
     {
-      win = child;
-      event.m_x -= child->m_x;
-      event.m_y -= child->m_y;
-      break;
+      wxWindow *child = (wxWindow*)node->Data();
+      if ((child->m_x <= event.m_x) &&
+          (child->m_y <= event.m_y) &&
+         (child->m_x+child->m_width  >= event.m_x) &&
+         (child->m_y+child->m_height >= event.m_y))
+      {
+        win = child;
+        event.m_x -= child->m_x;
+        event.m_y -= child->m_y;
+        break;
+      }
+      node = node->Next();
     }
-    node = node->Next();
   }
   
   event.SetEventObject( win );
@@ -468,6 +477,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
 static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
 { 
   if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
+  
   if (g_blockEventsOnDrag) return TRUE;
 
   if (!win->HasVMT()) return TRUE;
@@ -494,21 +504,24 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
   // Some control don't have their own X window and thus cannot get
   // any events. 
   
-  wxNode *node = win->GetChildren()->First();
-  while (node)
+  if (!g_capturing)
   {
-    wxWindow *child = (wxWindow*)node->Data();
-    if ((child->m_x <= event.m_x) &&
-        (child->m_y <= event.m_y) &&
-       (child->m_x+child->m_width  >= event.m_x) &&
-       (child->m_y+child->m_height >= event.m_y))
+    wxNode *node = win->GetChildren()->First();
+    while (node)
     {
-      win = child;
-      event.m_x -= child->m_x;
-      event.m_y -= child->m_y;
-      break;
+      wxWindow *child = (wxWindow*)node->Data();
+      if ((child->m_x <= event.m_x) &&
+          (child->m_y <= event.m_y) &&
+         (child->m_x+child->m_width  >= event.m_x) &&
+         (child->m_y+child->m_height >= event.m_y))
+      {
+        win = child;
+        event.m_x -= child->m_x;
+        event.m_y -= child->m_y;
+        break;
+      }
+      node = node->Next();
     }
-    node = node->Next();
   }
   
   event.SetEventObject( win );
@@ -591,6 +604,54 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED
   return TRUE;
 }
 
+//-----------------------------------------------------------------------------
+// "enter_notify_event"
+//-----------------------------------------------------------------------------
+
+static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
+{
+  if (widget->window != gdk_event->window) return TRUE;
+  
+  if (g_blockEventsOnDrag) return TRUE;
+  
+  if (!win->HasVMT()) return TRUE;
+  
+  if (widget->window)
+    gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() );
+    
+  wxMouseEvent event( wxEVT_ENTER_WINDOW );
+  event.SetEventObject( win );
+  
+  if (win->GetEventHandler()->ProcessEvent( event ))
+    gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "enter_notify_event" );
+  
+  return TRUE;
+}
+    
+//-----------------------------------------------------------------------------
+// "leave_notify_event"
+//-----------------------------------------------------------------------------
+
+static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
+{
+  if (widget->window != gdk_event->window) return TRUE;
+  
+  if (g_blockEventsOnDrag) return TRUE;
+  
+  if (!win->HasVMT()) return TRUE;
+  
+  if (widget->window)
+    gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() );
+    
+  wxMouseEvent event( wxEVT_LEAVE_WINDOW );
+  event.SetEventObject( win );
+  
+  if (win->GetEventHandler()->ProcessEvent( event ))
+    gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "leave_notify_event" );
+  
+  return TRUE;
+}
+    
 //-----------------------------------------------------------------------------
 // "value_changed" from m_vAdjust
 //-----------------------------------------------------------------------------
@@ -739,42 +800,6 @@ static void gtk_window_drop_callback( GtkWidget *widget, GdkEvent *event, wxWind
 */
 }
 
-//-----------------------------------------------------------------------------
-// "enter_notify_event"
-//-----------------------------------------------------------------------------
-
-static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
-{
-  if (widget->window != gdk_event->window) return TRUE;
-  if (g_blockEventsOnDrag) return TRUE;
-  if (!win->HasVMT()) return TRUE;
-  
-  if (widget->window)
-    gdk_window_set_cursor( widget->window, win->m_cursor->GetCursor() );
-    
-  wxMouseEvent event( wxEVT_ENTER_WINDOW );
-  event.SetEventObject( win );
-  return win->GetEventHandler()->ProcessEvent( event );
-}
-    
-//-----------------------------------------------------------------------------
-// "leave_notify_event"
-//-----------------------------------------------------------------------------
-
-static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
-{
-  if (widget->window != gdk_event->window) return TRUE;
-  if (!win->HasVMT()) return TRUE;
-  if (g_blockEventsOnDrag) return TRUE;
-  
-  if (widget->window)
-    gdk_window_set_cursor( widget->window, wxSTANDARD_CURSOR->GetCursor() );
-    
-  wxMouseEvent event( wxEVT_LEAVE_WINDOW );
-  event.SetEventObject( win );
-  return win->GetEventHandler()->ProcessEvent( event );
-}
-    
 //-----------------------------------------------------------------------------
 // wxWindow
 //-----------------------------------------------------------------------------
@@ -1019,11 +1044,6 @@ void wxWindow::PostCreation(void)
 {
   if (m_parent) m_parent->AddChild( this );
   
-//  GtkStyle *style = m_widget->style;
-//  style->font = m_font.GetInternalFont( 1.0 );          // destroy old font ?
-  
-  GtkWidget *connect_widget = GetConnectWidget();
   if (m_wxwindow)
   {
     gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", 
@@ -1033,52 +1053,46 @@ void wxWindow::PostCreation(void)
       GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this );
   }
   
-  gtk_signal_connect( GTK_OBJECT(connect_widget), "key_press_event",
+  ConnectWidget( GetConnectWidget() );
+  
+  if (m_widget && m_parent) gtk_widget_realize( m_widget );
+  
+  if (m_wxwindow)
+  {
+    gtk_widget_realize( m_wxwindow );
+    gdk_gc_set_exposures( m_wxwindow->style->fg_gc[0], TRUE );
+  }
+  
+  SetCursor( wxSTANDARD_CURSOR );
+  
+  m_hasVMT = TRUE;
+}
+
+void wxWindow::ConnectWidget( GtkWidget *widget )
+{
+  gtk_signal_connect( GTK_OBJECT(widget), "key_press_event",
     GTK_SIGNAL_FUNC(gtk_window_key_press_callback), (gpointer)this );
 
-  gtk_signal_connect( GTK_OBJECT(connect_widget), "button_press_event",
+  gtk_signal_connect( GTK_OBJECT(widget), "button_press_event",
     GTK_SIGNAL_FUNC(gtk_window_button_press_callback), (gpointer)this );
     
-  gtk_signal_connect( GTK_OBJECT(connect_widget), "button_release_event",
+  gtk_signal_connect( GTK_OBJECT(widget), "button_release_event",
     GTK_SIGNAL_FUNC(gtk_window_button_release_callback), (gpointer)this );
     
-  gtk_signal_connect( GTK_OBJECT(connect_widget), "motion_notify_event",
+  gtk_signal_connect( GTK_OBJECT(widget), "motion_notify_event",
     GTK_SIGNAL_FUNC(gtk_window_motion_notify_callback), (gpointer)this );
     
-  gtk_signal_connect( GTK_OBJECT(connect_widget), "focus_in_event", 
+  gtk_signal_connect( GTK_OBJECT(widget), "focus_in_event", 
     GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
 
-  gtk_signal_connect( GTK_OBJECT(connect_widget), "focus_out_event", 
+  gtk_signal_connect( GTK_OBJECT(widget), "focus_out_event", 
     GTK_SIGNAL_FUNC(gtk_window_focus_out_callback), (gpointer)this );
 
-  // Only for cursor handling
-    
-  gtk_signal_connect( GTK_OBJECT(m_widget), "enter_notify_event", 
+  gtk_signal_connect( GTK_OBJECT(widget), "enter_notify_event", 
     GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
     
-  gtk_signal_connect( GTK_OBJECT(m_widget), "leave_notify_event", 
+  gtk_signal_connect( GTK_OBJECT(widget), "leave_notify_event", 
     GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
-    
-  if (m_wxwindow)
-  {
-    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "enter_notify_event", 
-      GTK_SIGNAL_FUNC(gtk_window_enter_callback), (gpointer)this );
-      
-    gtk_signal_connect( GTK_OBJECT(m_wxwindow), "leave_notify_event", 
-      GTK_SIGNAL_FUNC(gtk_window_leave_callback), (gpointer)this );
-  }
-  
-  if (m_widget && m_parent) gtk_widget_realize( m_widget );
-  
-  if (m_wxwindow)
-  {
-    gtk_widget_realize( m_wxwindow );
-    gdk_gc_set_exposures( m_wxwindow->style->fg_gc[0], TRUE );
-  }
-  
-  SetCursor( wxSTANDARD_CURSOR );
-  
-  m_hasVMT = TRUE;
 }
 
 bool wxWindow::HasVMT(void)
@@ -1887,22 +1901,12 @@ void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
 {
   GtkWidget *dnd_widget = GetConnectWidget();
   
-  if (m_pDropTarget)
-  {
-    gtk_signal_disconnect_by_func( GTK_OBJECT(dnd_widget),
-      GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
+  DisconnectDnDWidget( dnd_widget );
   
-    m_pDropTarget->UnregisterWidget( dnd_widget );
-    delete m_pDropTarget;
-  }
+  if (m_pDropTarget) delete m_pDropTarget;
   m_pDropTarget = dropTarget;
-  if (m_pDropTarget)
-  {
-    m_pDropTarget->RegisterWidget( dnd_widget );
-    
-    gtk_signal_connect( GTK_OBJECT(dnd_widget), "drop_data_available_event",
-      GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
-  }
+  
+  ConnectDnDWidget( dnd_widget );
 }
 
 wxDropTarget *wxWindow::GetDropTarget() const
@@ -1910,6 +1914,26 @@ wxDropTarget *wxWindow::GetDropTarget() const
   return m_pDropTarget;
 }
 
+void wxWindow::ConnectDnDWidget( GtkWidget *widget )
+{
+  if (!m_pDropTarget) return;
+  
+  m_pDropTarget->RegisterWidget( widget );
+    
+  gtk_signal_connect( GTK_OBJECT(widget), "drop_data_available_event",
+    GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
+}
+
+void wxWindow::DisconnectDnDWidget( GtkWidget *widget )
+{
+  if (!m_pDropTarget) return;
+  
+  gtk_signal_disconnect_by_func( GTK_OBJECT(widget),
+    GTK_SIGNAL_FUNC(gtk_window_drop_callback), (gpointer)this );
+  
+  m_pDropTarget->UnregisterWidget( widget );
+}
+
 GtkWidget* wxWindow::GetConnectWidget(void)
 {
   GtkWidget *connect_widget = m_widget;
@@ -1926,20 +1950,12 @@ bool wxWindow::IsOwnGtkWindow( GdkWindow *window )
 
 void wxWindow::SetFont( const wxFont &font )
 {
-  m_font = font;
-
-  // Unfortunately this results in a crash in GTK on deletion
-  // of windows, e.g. the wxStatusBar in Dialog Editor.
-#if 0
-
-  // ADDED BY JACS: not sure if this is the right thing to do,
-  // but will avoid a segv when SetFont(wxNullFont) is called.
-  if (((wxFont*) &font)->Ok())
+  if (((wxFont*)&font)->Ok())
     m_font = font;
   else
     m_font = *wxSWISS_FONT;
 
-  GtkStyle *style = (GtkStyle`*) NULL;
+  GtkStyle *style = (GtkStyle*) NULL;
   if (!m_hasOwnStyle)
   {
     m_hasOwnStyle = TRUE;
@@ -1954,7 +1970,6 @@ void wxWindow::SetFont( const wxFont &font )
   style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
   
   gtk_widget_set_style( m_widget, style );
-#endif
 }
 
 wxFont *wxWindow::GetFont(void)
@@ -1982,6 +1997,7 @@ void wxWindow::CaptureMouse(void)
         GDK_BUTTON_RELEASE_MASK |
         GDK_POINTER_MOTION_MASK), 
         (GdkWindow *) NULL, (GdkCursor *) NULL, GDK_CURRENT_TIME );
+  g_capturing = TRUE;
 }
 
 void wxWindow::ReleaseMouse(void)
@@ -1989,6 +2005,7 @@ void wxWindow::ReleaseMouse(void)
   GtkWidget *connect_widget = GetConnectWidget();
   gtk_grab_remove( connect_widget );
   gdk_pointer_ungrab ( GDK_CURRENT_TIME );
+  g_capturing = FALSE;
 }
 
 void wxWindow::SetTitle( const wxString &WXUNUSED(title) )