]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
Build fixes
[wxWidgets.git] / src / gtk / window.cpp
index 239505cf504d4e903cb63c51744f55d22d04eb2b..9dc17c0291c202d77fe18046276d520438e697a4 100644 (file)
 extern wxList wxPendingDelete;
 extern wxList wxTopLevelWindows;
 extern bool   g_blockEventsOnDrag;
+extern bool   g_blockEventsOnScroll;
 static bool   g_capturing = FALSE;
 
 // hack: we need something to pass to gtk_menu_popup, so we store the time of
@@ -186,15 +187,15 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle
 
 static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
 {
-    printf( "OnKeyPress.\n " );
-    
     if (!win->HasVMT()) return FALSE;
     if (g_blockEventsOnDrag) return FALSE;
 
+/*
     printf( "OnKeyPress from " );
     if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
         printf( win->GetClassInfo()->GetClassName() );
     printf( ".\n" );
+*/
 
     long key_code = 0;
     switch (gdk_event->keyval)
@@ -286,19 +287,13 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
     event.m_y = 0;
     event.SetEventObject( win );
 
-    printf( "process key.\n" );
-    
     bool ret = win->GetEventHandler()->ProcessEvent( event );
 
-    printf( "no handler.\n" );
-    
     if (!ret)
     {
         wxWindow *ancestor = win;
         while (ancestor)
         {
-            printf( "check accel in %s .\n", WXSTRINGCAST ancestor->GetName() );
-           
             int command = ancestor->GetAcceleratorTable()->GetCommand( event );
             if (command != -1)
             {
@@ -328,6 +323,7 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
     if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
 
     if (g_blockEventsOnDrag) return TRUE;
+    if (g_blockEventsOnScroll) return TRUE;
 
     if (win->m_wxwindow)
     {
@@ -438,6 +434,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
     if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
 
     if (g_blockEventsOnDrag) return TRUE;
+    if (g_blockEventsOnScroll) return TRUE;
 
     if (!win->HasVMT()) return TRUE;
 
@@ -508,7 +505,8 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
     if (!win->IsOwnGtkWindow( gdk_event->window )) return TRUE;
 
     if (g_blockEventsOnDrag) return TRUE;
-
+    if (g_blockEventsOnScroll) return TRUE;
+    
     if (!win->HasVMT()) return TRUE;
 
 /*
@@ -720,13 +718,20 @@ static void gtk_window_vscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *
     float line_step = win->m_vAdjust->step_increment;
     float page_step = win->m_vAdjust->page_increment;
 
-    if (fabs(win->m_vAdjust->value-win->m_vAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM;
-    else if (fabs(win->m_vAdjust->value-win->m_vAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP;
-    else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
-    else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
-    else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
-    else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
-    else command = wxEVT_SCROLL_THUMBTRACK;
+    if (win->m_isScrolling)
+    {
+        command = wxEVT_SCROLL_THUMBTRACK;
+    }
+    else
+    {
+        if (fabs(win->m_vAdjust->value-win->m_vAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM;
+        else if (fabs(win->m_vAdjust->value-win->m_vAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP;
+        else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+        else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+        else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+        else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+        else command = wxEVT_SCROLL_THUMBTRACK;
+    }
 
     int value = (int)(win->m_vAdjust->value+0.5);
 
@@ -760,13 +765,20 @@ static void gtk_window_hscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow *
     float line_step = win->m_hAdjust->step_increment;
     float page_step = win->m_hAdjust->page_increment;
     
-    if (fabs(win->m_hAdjust->value-win->m_hAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM;
-    else if (fabs(win->m_hAdjust->value-win->m_hAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP;
-    else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
-    else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
-    else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
-    else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
-    else command = wxEVT_SCROLL_THUMBTRACK;
+    if (win->m_isScrolling)
+    {
+        command = wxEVT_SCROLL_THUMBTRACK;
+    }
+    else
+    {
+        if (fabs(win->m_hAdjust->value-win->m_hAdjust->lower) < 0.2) command = wxEVT_SCROLL_BOTTOM;
+        else if (fabs(win->m_hAdjust->value-win->m_hAdjust->upper) < 0.2) command = wxEVT_SCROLL_TOP;
+        else if (fabs(diff-line_step) < 0.2) command = wxEVT_SCROLL_LINEDOWN;
+        else if (fabs(diff+line_step) < 0.2) command = wxEVT_SCROLL_LINEUP;
+        else if (fabs(diff-page_step) < 0.2) command = wxEVT_SCROLL_PAGEDOWN;
+        else if (fabs(diff+page_step) < 0.2) command = wxEVT_SCROLL_PAGEUP;
+        else command = wxEVT_SCROLL_THUMBTRACK;
+    }
 
     int value = (int)(win->m_hAdjust->value+0.5);
 
@@ -829,11 +841,14 @@ static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxW
 // "button_press_event" from scrollbar
 //-----------------------------------------------------------------------------
 
-static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButton *gdk_event, wxWindow *win )
+static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget), 
+                                                 GdkEventButton *WXUNUSED(gdk_event), 
+                                                wxWindow *win )
 {
-    if (gdk_event->window != widget->slider) return FALSE;
-
+//    if (gdk_event->window != widget->slider) return FALSE;
+    
     win->m_isScrolling = TRUE;
+    g_blockEventsOnScroll = TRUE;
 
     return FALSE;
 }
@@ -842,9 +857,15 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *widget, GdkEventButto
 // "button_release_event" from scrollbar
 //-----------------------------------------------------------------------------
 
-static gint gtk_scrollbar_button_release_callback( GtkRange *widget, GdkEventButton *gdk_event, wxWindow *win )
+static gint gtk_scrollbar_button_release_callback( GtkRange *widget, 
+                                                   GdkEventButton *WXUNUSED(gdk_event), 
+                                                  wxWindow *win )
 {
-    if (gdk_event->window != widget->slider) return FALSE;
+
+//  don't test here as we can reelase the mouse while being over
+//  a different window then the slider
+//
+//    if (gdk_event->window != widget->slider) return FALSE;
 
     GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(win->m_widget);
 
@@ -854,6 +875,7 @@ static gint gtk_scrollbar_button_release_callback( GtkRange *widget, GdkEventBut
         gtk_signal_emit_by_name( GTK_OBJECT(win->m_vAdjust), "value_changed" );
 
     win->m_isScrolling = FALSE;
+    g_blockEventsOnScroll = FALSE;
 
     return FALSE;
 }
@@ -976,18 +998,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id,
 
     GtkScrolledWindow *s_window = GTK_SCROLLED_WINDOW(m_widget);
 
-    gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_press_event",
-          (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
-
-    gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event",
-          (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
-
-    gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event",
-          (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
-
-    gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event",
-          (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
-
     GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
     scroll_class->scrollbar_spacing = 0;
 
@@ -999,16 +1009,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id,
     m_hAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->hscrollbar) );
     m_vAdjust = gtk_range_get_adjustment( GTK_RANGE(s_window->vscrollbar) );
 
-    gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
-          (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
-    gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
-          (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
-
-    gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
-          (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
-    gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
-          (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
-
     m_wxwindow = gtk_myfixed_new();
 
 #ifdef NEW_GTK_SCROLL_CODE
@@ -1057,6 +1057,36 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id,
     m_hAdjust->page_size = 5.0;
     gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "changed" );
 
+    // these handlers block mouse events to any window during scrolling
+    // such as motion events and prevent GTK and wxWindows from fighting
+    // over where the slider should be
+    
+    gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_press_event",
+          (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
+
+    gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_press_event",
+          (GtkSignalFunc)gtk_scrollbar_button_press_callback, (gpointer) this );
+
+    gtk_signal_connect( GTK_OBJECT(s_window->vscrollbar), "button_release_event",
+          (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
+
+    gtk_signal_connect( GTK_OBJECT(s_window->hscrollbar), "button_release_event",
+          (GtkSignalFunc)gtk_scrollbar_button_release_callback, (gpointer) this );
+         
+    // these handers het notified when screen updates are required either when
+    // scrolling or when the window size (and therefore scrollbar configuration)
+    // has changed
+
+    gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
+          (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
+    gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
+          (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
+
+    gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
+          (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
+    gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
+          (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
+
     gtk_widget_show( m_wxwindow );
   
     if (m_parent) m_parent->AddChild( this );
@@ -1448,13 +1478,13 @@ void wxWindow::SetClientSize( int width, int height )
         dh += 2 * viewport_class->ythickness;
       }
 
-      if (GTK_WIDGET_VISIBLE(vscrollbar))
+      if (scroll_window->vscrollbar_visible)
       {
         dw += vscrollbar->allocation.width;
         dw += scroll_class->scrollbar_spacing;
       }
 
-      if (GTK_WIDGET_VISIBLE(hscrollbar))
+      if (scroll_window->hscrollbar_visible)
       {
         dh += hscrollbar->allocation.height;
         dw += scroll_class->scrollbar_spacing;
@@ -1503,9 +1533,6 @@ void wxWindow::GetClientSize( int *width, int *height ) const
 
       GtkStyleClass *viewport_class = viewport->style->klass;
 
-      GtkWidget *hscrollbar = scroll_window->hscrollbar;
-      GtkWidget *vscrollbar = scroll_window->vscrollbar;
-
       if ((m_windowStyle & wxRAISED_BORDER) ||
           (m_windowStyle & wxSUNKEN_BORDER))
       {
@@ -1513,14 +1540,14 @@ void wxWindow::GetClientSize( int *width, int *height ) const
         dh += 2 * viewport_class->ythickness;
       }
 
-      if (GTK_WIDGET_VISIBLE(vscrollbar))
+      if (scroll_window->vscrollbar_visible)
       {
 //        dw += vscrollbar->allocation.width;
         dw += 15;                               // range.slider_width = 11 + 2*2pts edge
         dw += scroll_class->scrollbar_spacing;
       }
 
-      if (GTK_WIDGET_VISIBLE(hscrollbar))
+      if (scroll_window->hscrollbar_visible)
       {
 //        dh += hscrollbar->allocation.height;
         dh += 15;
@@ -1662,7 +1689,7 @@ void wxWindow::SetSizeHints( int minW, int minH, int maxW, int maxH, int WXUNUSE
 
 void wxWindow::OnSize( wxSizeEvent &WXUNUSED(event) )
 {
-  //if (GetAutoLayout()) Layout();
+  if (GetAutoLayout()) Layout();
 }
 
 bool wxWindow::Show( bool show )
@@ -1702,38 +1729,38 @@ int wxWindow::GetCharHeight() const
 
 int wxWindow::GetCharWidth() const
 {
-  wxASSERT_MSG( (m_widget != NULL), "invalid window" );
+    wxASSERT_MSG( (m_widget != NULL), "invalid window" );
 
-  if (!m_font.Ok())
-  {
-    wxFAIL_MSG( "invalid font" );
-    return -1;
-  }
+    if (!m_font.Ok())
+    {
+      wxFAIL_MSG( "invalid font" );
+      return -1;
+    }
 
-  GdkFont *font = m_font.GetInternalFont( 1.0 );
-  return gdk_string_width( font, "H" );
+    GdkFont *font = m_font.GetInternalFont( 1.0 );
+    return gdk_string_width( font, "H" );
 }
 
 void wxWindow::GetTextExtent( const wxString& string, int *x, int *y,
   int *descent, int *externalLeading, const wxFont *theFont, bool WXUNUSED(use16) ) const
 {
-  wxASSERT_MSG( (m_widget != NULL), "invalid window" );
+    wxASSERT_MSG( (m_widget != NULL), "invalid window" );
 
-  wxFont fontToUse = m_font;
-  if (theFont) fontToUse = *theFont;
+    wxFont fontToUse = m_font;
+    if (theFont) fontToUse = *theFont;
 
-  if (!fontToUse.Ok())
-  {
-    wxFAIL_MSG( "invalid font" );
-    return;
-  }
-  wxASSERT_MSG( (m_font.Ok()), "invalid font" );
+    if (!fontToUse.Ok())
+    {
+      wxFAIL_MSG( "invalid font" );
+      return;
+    }
+    wxASSERT_MSG( (m_font.Ok()), "invalid font" );
 
-  GdkFont *font = fontToUse.GetInternalFont( 1.0 );
-  if (x) (*x) = gdk_string_width( font, string );
-  if (y) (*y) = font->ascent + font->descent;
-  if (descent) (*descent) = font->descent;
-  if (externalLeading) (*externalLeading) = 0;  // ??
+    GdkFont *font = fontToUse.GetInternalFont( 1.0 );
+    if (x) (*x) = gdk_string_width( font, string );
+    if (y) (*y) = font->ascent + font->descent;
+    if (descent) (*descent) = font->descent;
+    if (externalLeading) (*externalLeading) = 0;  // ??
 }
 
 void wxWindow::MakeModal( bool modal )
@@ -1756,105 +1783,122 @@ void wxWindow::MakeModal( bool modal )
 
 void wxWindow::SetFocus()
 {
-  wxASSERT_MSG( (m_widget != NULL), "invalid window" );
+    wxASSERT_MSG( (m_widget != NULL), "invalid window" );
 
-  GtkWidget *connect_widget = GetConnectWidget();
-  if (connect_widget)
-  {
-    if (GTK_WIDGET_CAN_FOCUS(connect_widget) && !GTK_WIDGET_HAS_FOCUS (connect_widget) )
+    GtkWidget *connect_widget = GetConnectWidget();
+    if (connect_widget)
     {
-      gtk_widget_grab_focus (connect_widget);
+        if (GTK_WIDGET_CAN_FOCUS(connect_widget) && !GTK_WIDGET_HAS_FOCUS (connect_widget) )
+        {
+            gtk_widget_grab_focus (connect_widget);
+        }
     }
-  }
 }
 
 bool wxWindow::OnClose()
 {
-  return TRUE;
+    return TRUE;
 }
 
 void wxWindow::AddChild( wxWindow *child )
 {
-  wxASSERT_MSG( (m_widget != NULL), "invalid window" );
-  wxASSERT_MSG( (child != NULL), "invalid child" );
+    wxASSERT_MSG( (m_widget != NULL), "invalid window" );
+    wxASSERT_MSG( (child != NULL), "invalid child" );
 
-  m_children.Append( child );
+    m_children.Append( child );
 }
 
 wxList *wxWindow::GetChildren()
 {
-  return (&m_children);
+    return (&m_children);
+}
+
+wxWindow *wxWindow::ReParent( wxWindow *newParent )
+{
+  wxWindow *oldParent = GetParent();
+  
+  if (oldParent) oldParent->RemoveChild( this );
+  
+  gtk_widget_unparent( m_widget );
+  
+  if (newParent)
+  {
+     newParent->AddChild( this );
+     (newParent->m_insertCallback)( newParent, this );
+  }
+  
+  return oldParent;
 }
 
 void wxWindow::RemoveChild( wxWindow *child )
 {
-  if (GetChildren()) GetChildren()->DeleteObject( child );
-  child->m_parent = (wxWindow *) NULL;
+    if (GetChildren()) GetChildren()->DeleteObject( child );
+    child->m_parent = (wxWindow *) NULL;
 }
 
 void wxWindow::SetReturnCode( int retCode )
 {
-  m_retCode = retCode;
+    m_retCode = retCode;
 }
 
 int wxWindow::GetReturnCode()
 {
-  return m_retCode;
+    return m_retCode;
 }
 
 void wxWindow::Raise()
 {
-  wxASSERT_MSG( (m_widget != NULL), "invalid window" );
+    wxASSERT_MSG( (m_widget != NULL), "invalid window" );
 
-  if (m_widget) gdk_window_raise( m_widget->window );
+    if (m_widget) gdk_window_raise( m_widget->window );
 }
 
 void wxWindow::Lower()
 {
-  wxASSERT_MSG( (m_widget != NULL), "invalid window" );
+    wxASSERT_MSG( (m_widget != NULL), "invalid window" );
 
-  if (m_widget) gdk_window_lower( m_widget->window );
+    if (m_widget) gdk_window_lower( m_widget->window );
 }
 
 wxEvtHandler *wxWindow::GetEventHandler()
 {
-  return m_eventHandler;
+    return m_eventHandler;
 }
 
 void wxWindow::SetEventHandler( wxEvtHandler *handler )
 {
-  m_eventHandler = handler;
+    m_eventHandler = handler;
 }
 
 void wxWindow::PushEventHandler(wxEvtHandler *handler)
 {
-  handler->SetNextHandler(GetEventHandler());
-  SetEventHandler(handler);
+    handler->SetNextHandler(GetEventHandler());
+    SetEventHandler(handler);
 }
 
 wxEvtHandler *wxWindow::PopEventHandler(bool deleteHandler)
 {
-  if (GetEventHandler())
-  {
-    wxEvtHandler *handlerA = GetEventHandler();
-    wxEvtHandler *handlerB = handlerA->GetNextHandler();
-    handlerA->SetNextHandler((wxEvtHandler *) NULL);
-    SetEventHandler(handlerB);
-    if (deleteHandler)
+    if (GetEventHandler())
     {
-      delete handlerA;
-      return (wxEvtHandler*) NULL;
-    }
-    else
-      return handlerA;
-  }
-  else
-   return (wxEvtHandler *) NULL;
+        wxEvtHandler *handlerA = GetEventHandler();
+        wxEvtHandler *handlerB = handlerA->GetNextHandler();
+        handlerA->SetNextHandler((wxEvtHandler *) NULL);
+        SetEventHandler(handlerB);
+        if (deleteHandler)
+        {
+            delete handlerA;
+            return (wxEvtHandler*) NULL;
+        }
+        else
+            return handlerA;
+     }
+     else
+        return (wxEvtHandler *) NULL;
 }
 
 wxValidator *wxWindow::GetValidator()
 {
-  return m_windowValidator;
+    return m_windowValidator;
 }
 
 void wxWindow::SetValidator( const wxValidator& validator )