]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
Added #include wx/dcclient.h and wx/settings.h for Vadims new code under
[wxWidgets.git] / src / gtk / window.cpp
index 433694c88ce6a4f689c1463b33c2843bbe26eb1c..2f86fc9602677682a8b0e43a772ff551cfdd6507 100644 (file)
@@ -44,9 +44,7 @@
 #include "gdk/gdkkeysyms.h"
 #include "wx/gtk/win_gtk.h"
 
 #include "gdk/gdkkeysyms.h"
 #include "wx/gtk/win_gtk.h"
 
-#if (GTK_MINOR_VERSION == 0)
 #include "gdk/gdkx.h"
 #include "gdk/gdkx.h"
-#endif
 
 //-----------------------------------------------------------------------------
 // documentation on internals
 
 //-----------------------------------------------------------------------------
 // documentation on internals
@@ -133,7 +131,7 @@ extern wxList     wxPendingDelete;
 extern bool       g_blockEventsOnDrag;
 extern bool       g_blockEventsOnScroll;
 extern wxCursor   g_globalCursor;
 extern bool       g_blockEventsOnDrag;
 extern bool       g_blockEventsOnScroll;
 extern wxCursor   g_globalCursor;
-static bool       g_capturing = FALSE;
+static wxWindow  *g_captureWindow = (wxWindow*) NULL;
 static wxWindow  *g_focusWindow = (wxWindow*) NULL;
 
 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
 static wxWindow  *g_focusWindow = (wxWindow*) NULL;
 
 /* hack: we need something to pass to gtk_menu_popup, so we store the time of
@@ -179,6 +177,32 @@ void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window
 
 #endif // Debug
 
 
 #endif // Debug
 
+//-----------------------------------------------------------------------------
+// missing gdk functions
+//-----------------------------------------------------------------------------
+
+void
+gdk_window_warp_pointer (GdkWindow      *window,
+                        gint            x,
+                        gint            y)
+{
+  GdkWindowPrivate *priv;
+  
+  if (!window)
+    window = (GdkWindow*) &gdk_root_parent;
+  
+  priv = (GdkWindowPrivate*) window;
+  
+  if (!priv->destroyed)
+  {
+      XWarpPointer (priv->xdisplay, 
+                    None,              /* not source window -> move from anywhere */
+                   priv->xwindow,  /* dest window */
+                    0, 0, 0, 0,        /* not source window -> move from anywhere */
+                   x, y );
+  }
+}
+
 //-----------------------------------------------------------------------------
 // idle system
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // idle system
 //-----------------------------------------------------------------------------
@@ -216,6 +240,12 @@ static long map_to_unmodified_wx_keysym( KeySym keysym )
         case GDK_Shift_R:       key_code = WXK_SHIFT;       break;
         case GDK_Control_L:
         case GDK_Control_R:     key_code = WXK_CONTROL;     break;
         case GDK_Shift_R:       key_code = WXK_SHIFT;       break;
         case GDK_Control_L:
         case GDK_Control_R:     key_code = WXK_CONTROL;     break;
+       case GDK_Meta_L:
+       case GDK_Meta_R:
+       case GDK_Alt_L:
+       case GDK_Alt_R:
+       case GDK_Super_L:
+       case GDK_Super_R:       key_code = WXK_ALT;         break;
         case GDK_Menu:          key_code = WXK_MENU;        break;
         case GDK_Help:          key_code = WXK_HELP;        break;
         case GDK_BackSpace:     key_code = WXK_BACK;        break;
         case GDK_Menu:          key_code = WXK_MENU;        break;
         case GDK_Help:          key_code = WXK_HELP;        break;
         case GDK_BackSpace:     key_code = WXK_BACK;        break;
@@ -601,25 +631,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
     
     key_code = map_to_wx_keysym( gdk_event->keyval );
 
     
     key_code = map_to_wx_keysym( gdk_event->keyval );
 
-    /* wxMSW doesn't send char events with Alt pressed */
-    if ((key_code != 0) &&
-        ((gdk_event->state & GDK_MOD1_MASK) == 0) &&
-        ((gdk_event->state & GDK_MOD1_MASK) == 0))
-    {
-        wxKeyEvent event2( wxEVT_CHAR );                 
-        event2.SetTimestamp( gdk_event->time );
-        event2.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
-        event2.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
-//        event2.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
-//        event2.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
-        event2.m_keyCode = key_code;
-        event2.m_scanCode = gdk_event->keyval;
-        event2.m_x = x;
-        event2.m_y = y;
-        event2.SetEventObject( win );
-        ret = (ret || win->GetEventHandler()->ProcessEvent( event2 ));
-    }
-
+#if wxUSE_ACCEL
     if (!ret)
     {
         wxWindow *ancestor = win;
     if (!ret)
     {
         wxWindow *ancestor = win;
@@ -635,6 +647,26 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
             ancestor = ancestor->GetParent();
         }
     }
             ancestor = ancestor->GetParent();
         }
     }
+#endif // wxUSE_ACCEL
+    /* wxMSW doesn't send char events with Alt pressed */
+    /* Only send wxEVT_CHAR event if not processed yet. Thus, ALT-x
+       will only be sent if it is not a menu accelerator. */
+    if ((key_code != 0) && ! ret )
+    {
+        wxKeyEvent event2( wxEVT_CHAR );                 
+        event2.SetTimestamp( gdk_event->time );
+        event2.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
+        event2.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK);
+        event2.m_altDown = (gdk_event->state & GDK_MOD1_MASK);
+        event2.m_metaDown = (gdk_event->state & GDK_MOD2_MASK);
+        event2.m_keyCode = key_code;
+        event2.m_scanCode = gdk_event->keyval;
+        event2.m_x = x;
+        event2.m_y = y;
+        event2.SetEventObject( win );
+        ret = (ret || win->GetEventHandler()->ProcessEvent( event2 ));
+    }
+
 
     /* win is a control: tab can be propagated up */
     if ( (!ret) &&
 
     /* win is a control: tab can be propagated up */
     if ( (!ret) &&
@@ -676,8 +708,8 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
                     wxNode *node = menubar->GetMenus().First();
                    if (node)
                    {
                     wxNode *node = menubar->GetMenus().First();
                    if (node)
                    {
-                        wxMenu *firstMenu = (wxMenu*) node->Data();
                        // doesn't work correctly
                        // doesn't work correctly
+            // wxMenu *firstMenu = (wxMenu*) node->Data();
                        // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
                        // ret = TRUE;
                        break;
                        // gtk_menu_item_select( GTK_MENU_ITEM(firstMenu->m_owner) );
                        // ret = TRUE;
                        break;
@@ -867,7 +899,7 @@ 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.
 
     // Some control don't have their own X window and thus cannot get
     // any events.
 
-    if (!g_capturing)
+    if (!g_captureWindow)
     {
         wxNode *node = win->GetChildren().First();
         while (node)
     {
         wxNode *node = win->GetChildren().First();
         while (node)
@@ -977,7 +1009,7 @@ 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.
 
     // Some control don't have their own X window and thus cannot get
     // any events.
 
-    if (!g_capturing)
+    if (!g_captureWindow)
     {
         wxNode *node = win->GetChildren().First();
         while (node)
     {
         wxNode *node = win->GetChildren().First();
         while (node)
@@ -1088,7 +1120,7 @@ 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.
 
     // Some control don't have their own X window and thus cannot get
     // any events.
 
-    if (!g_capturing)
+    if (!g_captureWindow)
     {
         wxNode *node = win->GetChildren().First();
         while (node)
     {
         wxNode *node = win->GetChildren().First();
         while (node)
@@ -1619,7 +1651,7 @@ void wxWindow::Init()
     m_scrollGC = (GdkGC*) NULL;
     m_widgetStyle = (GtkStyle*) NULL;
 
     m_scrollGC = (GdkGC*) NULL;
     m_widgetStyle = (GtkStyle*) NULL;
 
-    m_insertCallback = wxInsertChildInWindow;
+    m_insertCallback = (wxInsertChildFunction) NULL;
 
     m_isStaticBox = FALSE;
     m_acceptsFocus = FALSE;
 
     m_isStaticBox = FALSE;
     m_acceptsFocus = FALSE;
@@ -1645,6 +1677,8 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id,
 {
     PreCreation( parent, id, pos, size, style, name );
 
 {
     PreCreation( parent, id, pos, size, style, name );
 
+    m_insertCallback = wxInsertChildInWindow;
+
     m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
     GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
 
     m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
     GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
 
@@ -1949,7 +1983,7 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
     }
     else
     {
     }
     else
     {
-        if ((sizeFlags & wxSIZE_USE_EXISTING) == wxSIZE_USE_EXISTING)
+        if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
         {
             if (x != -1) m_x = x;
             if (y != -1) m_y = y;
         {
             if (x != -1) m_x = x;
             if (y != -1) m_y = y;
@@ -2029,18 +2063,18 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
 
 void wxWindow::OnInternalIdle()
 {
 
 void wxWindow::OnInternalIdle()
 {
-    GdkWindow *window = GetConnectWidget()->window;
-    if (window)
-    {
-        wxCursor cursor = m_cursor;
-        if (g_globalCursor.Ok()) cursor = g_globalCursor;
+        GdkWindow *window = GetConnectWidget()->window;
+        if (window)
+        {
+            wxCursor cursor = m_cursor;
+            if (g_globalCursor.Ok()) cursor = g_globalCursor;
        
        
-       if (m_currentGdkCursor != cursor)
-       {
-           gdk_window_set_cursor( window, cursor.GetCursor() );
-           m_currentGdkCursor = cursor;
+           if (cursor.Ok() && m_currentGdkCursor != cursor)
+           {
+               gdk_window_set_cursor( window, cursor.GetCursor() );
+               m_currentGdkCursor = cursor;
+           }
        }
        }
-    }
 
     UpdateWindowUI();
 }
 
     UpdateWindowUI();
 }
@@ -2351,15 +2385,41 @@ bool wxWindow::AcceptsFocus() const
 bool wxWindow::Reparent( wxWindow *newParent )
 {
     wxCHECK_MSG( (m_widget != NULL), (wxWindow*) NULL, _T("invalid window") );
 bool wxWindow::Reparent( wxWindow *newParent )
 {
     wxCHECK_MSG( (m_widget != NULL), (wxWindow*) NULL, _T("invalid window") );
-
-    gtk_widget_unparent( m_widget );
+    
+    wxWindow *oldParent = m_parent;
 
     if ( !wxWindowBase::Reparent(newParent) )
         return FALSE;
 
 
     if ( !wxWindowBase::Reparent(newParent) )
         return FALSE;
 
+    if (oldParent)
+    {
+        gtk_container_remove( GTK_CONTAINER(oldParent->m_wxwindow), m_widget );
+    }
+    
+    if (newParent)
+    {
+        /* insert GTK representation */
+        (*(newParent->m_insertCallback))(newParent, this);
+    }
+    
     return TRUE;
 }
 
     return TRUE;
 }
 
+void wxWindow::DoAddChild(wxWindow *child) 
+{
+    wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
+
+    wxASSERT_MSG( (child != NULL), _T("invalid child window") );
+
+    wxASSERT_MSG( (m_insertCallback != NULL), _T("invalid child insertion function") );
+    
+    /* add to list */
+    AddChild( child );
+    
+    /* insert GTK representation */
+    (*m_insertCallback)(this, child);
+}
+
 void wxWindow::Raise()
 {
     wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
 void wxWindow::Raise()
 {
     wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
@@ -2407,9 +2467,17 @@ bool wxWindow::SetCursor( const wxCursor &cursor )
     return TRUE;
 }
 
     return TRUE;
 }
 
-void wxWindow::WarpPointer( int WXUNUSED(x), int WXUNUSED(y) )
+void wxWindow::WarpPointer( int x, int y )
 {
 {
-    // TODO
+    wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+
+    GtkWidget *connect_widget = GetConnectWidget();
+    if (connect_widget->window)
+    {
+        /* we provide this function ourselves as it is
+          missing in GDK */
+        gdk_window_warp_pointer( connect_widget->window, x, y );
+    }
 }
 
 void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
 }
 
 void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
@@ -2477,7 +2545,7 @@ void wxWindow::DoSetToolTip( wxToolTip *tip )
 
 void wxWindow::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
 {
 
 void wxWindow::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
 {
-    gtk_tooltips_set_tip( tips, GetConnectWidget(), wxConv_current->cWX2MB(tip), (gchar*) NULL );
+    gtk_tooltips_set_tip( tips, GetConnectWidget(), wxConvCurrent->cWX2MB(tip), (gchar*) NULL );
 }
 #endif // wxUSE_TOOLTIPS
 
 }
 #endif // wxUSE_TOOLTIPS
 
@@ -2514,7 +2582,6 @@ bool wxWindow::SetBackgroundColour( const wxColour &colour )
     }
 
     wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
     }
 
     wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
-
     if (sysbg == m_backgroundColour)
     {
         m_backgroundColour = wxNullColour;
     if (sysbg == m_backgroundColour)
     {
         m_backgroundColour = wxNullColour;
@@ -2553,7 +2620,7 @@ bool wxWindow::SetForegroundColour( const wxColour &colour )
     }
 
     wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
     }
 
     wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
-    if (sysbg == m_foregroundColour)
+    if ( sysbg == m_backgroundColour )
     {
         m_backgroundColour = wxNullColour;
         ApplyWidgetStyle();
     {
         m_backgroundColour = wxNullColour;
         ApplyWidgetStyle();
@@ -2735,35 +2802,33 @@ void wxWindow::CaptureMouse()
 {
     wxCHECK_RET( m_widget != NULL, _T("invalid window") );
 
 {
     wxCHECK_RET( m_widget != NULL, _T("invalid window") );
 
-    wxCHECK_RET( g_capturing == FALSE, _T("CaptureMouse called twice") );
+    wxCHECK_RET( g_captureWindow == NULL, _T("CaptureMouse called twice") );
 
     GtkWidget *connect_widget = GetConnectWidget();
     if (!connect_widget->window) return;
     
 
     GtkWidget *connect_widget = GetConnectWidget();
     if (!connect_widget->window) return;
     
-    gtk_grab_add( connect_widget );
     gdk_pointer_grab( connect_widget->window, FALSE,
                       (GdkEventMask)
                          (GDK_BUTTON_PRESS_MASK |
                           GDK_BUTTON_RELEASE_MASK |
                           GDK_POINTER_MOTION_MASK),
                       (GdkWindow *) NULL,
     gdk_pointer_grab( connect_widget->window, FALSE,
                       (GdkEventMask)
                          (GDK_BUTTON_PRESS_MASK |
                           GDK_BUTTON_RELEASE_MASK |
                           GDK_POINTER_MOTION_MASK),
                       (GdkWindow *) NULL,
-                      (GdkCursor *) NULL,
+                      m_cursor.GetCursor(),
                       GDK_CURRENT_TIME );
                       GDK_CURRENT_TIME );
-    g_capturing = TRUE;
+    g_captureWindow = this;
 }
 
 void wxWindow::ReleaseMouse()
 {
     wxCHECK_RET( m_widget != NULL, _T("invalid window") );
 
 }
 
 void wxWindow::ReleaseMouse()
 {
     wxCHECK_RET( m_widget != NULL, _T("invalid window") );
 
-    wxCHECK_RET( g_capturing == TRUE, _T("ReleaseMouse called twice") );
+    wxCHECK_RET( g_captureWindow, _T("ReleaseMouse called twice") );
 
     GtkWidget *connect_widget = GetConnectWidget();
     if (!connect_widget->window) return;
     
 
     GtkWidget *connect_widget = GetConnectWidget();
     if (!connect_widget->window) return;
     
-    gtk_grab_remove( connect_widget );
     gdk_pointer_ungrab ( GDK_CURRENT_TIME );
     gdk_pointer_ungrab ( GDK_CURRENT_TIME );
-    g_capturing = FALSE;
+    g_captureWindow = (wxWindow*) NULL;
 }
 
 bool wxWindow::IsRetained() const
 }
 
 bool wxWindow::IsRetained() const
@@ -2926,7 +2991,10 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
     while (node)
     {
         wxWindow *child = (wxWindow*) node->Data();
     while (node)
     {
         wxWindow *child = (wxWindow*) node->Data();
-       child->Move( child->m_x + dx, child->m_y + dy );
+       int sx = 0;
+       int sy = 0;
+       child->GetSize( &sx, &sy );
+       child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
        node = node->Next();
     }
 
        node = node->Next();
     }