Author: kelnos
Date: 2006-07-12 10:27:45 +0000 (Wed, 12 Jul 2006)
New Revision: 22416

Modified:
   xfdesktop/trunk/src/xfdesktop-file-icon.c
   xfdesktop/trunk/src/xfdesktop-icon-view.c
Log:
finish implementing an icon-hover tooltip for the file icons (bug 1526)


Modified: xfdesktop/trunk/src/xfdesktop-file-icon.c
===================================================================
--- xfdesktop/trunk/src/xfdesktop-file-icon.c   2006-07-12 09:48:28 UTC (rev 
22415)
+++ xfdesktop/trunk/src/xfdesktop-file-icon.c   2006-07-12 10:27:45 UTC (rev 
22416)
@@ -206,6 +206,9 @@
     if(icon->priv->volume)
         g_object_unref(G_OBJECT(icon->priv->volume));
     
+    if(icon->priv->tooltip)
+        g_free(icon->priv->tooltip);
+    
     g_free(icon->priv);
     
     G_OBJECT_CLASS(xfdesktop_file_icon_parent_class)->finalize(obj);

Modified: xfdesktop/trunk/src/xfdesktop-icon-view.c
===================================================================
--- xfdesktop/trunk/src/xfdesktop-icon-view.c   2006-07-12 09:48:28 UTC (rev 
22415)
+++ xfdesktop/trunk/src/xfdesktop-icon-view.c   2006-07-12 10:27:45 UTC (rev 
22416)
@@ -53,6 +53,8 @@
 #define SCREEN_MARGIN     8
 #define CORNER_ROUNDNESS  4
 
+#define DEFAULT_TIP_TIMEOUT 500
+
 #if defined(DEBUG) && DEBUG > 0
 #define DUMP_GRID_LAYOUT(icon_view) \
 {\
@@ -143,6 +145,11 @@
     
     GdkPixbuf *rounded_frame;
     gint label_alpha;
+    
+    guint tip_show_id;
+    gint tip_timeout;
+    GtkWidget *tip_window;
+    GtkWidget *tip_label;
 };
 
 static gboolean xfdesktop_icon_view_button_press(GtkWidget *widget,
@@ -347,6 +354,8 @@
                                                         icon_view_n_targets);
     gtk_drag_dest_set(GTK_WIDGET(icon_view), 0, NULL, 0, GDK_ACTION_MOVE);
     
+    icon_view->priv->tip_timeout = DEFAULT_TIP_TIMEOUT;
+    
     GTK_WIDGET_SET_FLAGS(GTK_WIDGET(icon_view), GTK_NO_WINDOW);
 }
 
@@ -369,6 +378,11 @@
     g_list_free(icon_view->priv->icons);
     g_list_free(icon_view->priv->pending_icons);
     
+    if(icon_view->priv->tip_show_id)
+        g_source_remove(icon_view->priv->tip_show_id);
+    if(icon_view->priv->tip_window);
+        gtk_widget_destroy(icon_view->priv->tip_window);
+    
     g_free(icon_view->priv);
     
     G_OBJECT_CLASS(xfdesktop_icon_view_parent_class)->finalize(obj);
@@ -673,6 +687,143 @@
 }
 
 static gboolean
+xfdesktop_icon_view_tip_window_leave(GtkWidget *w,
+                                     GdkEventCrossing *evt,
+                                     gpointer user_data)
+{
+    XfdesktopIconView *icon_view = XFDESKTOP_ICON_VIEW(user_data);
+    GdkRectangle extents;
+    
+    if(icon_view->priv->item_under_pointer) {
+        GdkWindow *under_ptr;
+        
+        if(!xfdesktop_icon_get_extents(icon_view->priv->item_under_pointer,
+                                       &extents)
+           || !xfdesktop_rectangle_contains_point(&extents, evt->x_root,
+                                                  evt->y_root))
+        {
+            /* pointer is no longer over item */
+            gtk_widget_hide(w);
+        }
+        
+        under_ptr = 
gdk_display_get_window_at_pointer(gdk_display_get_default(),
+                                                      NULL, NULL);
+        if(under_ptr != icon_view->priv->parent_window->window) {
+            /* pointer is possibly still over the item, but the pointer is
+             * over another window that obscures the item */
+            XfdesktopIcon *icon = icon_view->priv->item_under_pointer;
+            icon_view->priv->item_under_pointer = NULL;
+#ifdef HAVE_LIBEXO
+            xfdesktop_icon_view_clear_icon_pixbuf_extents(icon_view, icon);
+#endif
+            if(GTK_WIDGET_VISIBLE(w))
+                gtk_widget_hide(w);
+        }
+    } else {
+        /* there's no item under the pointer for some reason anyway */
+        gtk_widget_hide(w);
+    }
+    
+    return FALSE;
+}
+
+static gboolean
+xfdesktop_icon_view_tip_window_expose(GtkWidget *w,
+                                      GdkEventExpose *evt,
+                                      gpointer user_data)
+{
+    GtkRequisition req;
+    
+    gtk_widget_size_request(w, &req);
+    gtk_paint_flat_box(w->style, w->window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
+                       NULL, w, "tooltip", 0, 0, req.width, req.height);
+}
+
+static void
+xfdesktop_icon_view_ensure_tip_window(XfdesktopIconView *icon_view)
+{
+    if(icon_view->priv->tip_window)
+        return;
+    
+    icon_view->priv->tip_window = gtk_window_new(GTK_WINDOW_POPUP);
+    gtk_window_set_resizable(GTK_WINDOW(icon_view->priv->tip_window), FALSE);
+    gtk_window_set_transient_for(GTK_WINDOW(icon_view->priv->tip_window),
+                                 GTK_WINDOW(icon_view->priv->parent_window));
+    gtk_container_set_border_width(GTK_CONTAINER(icon_view->priv->tip_window),
+                                   4);
+    gtk_widget_set_app_paintable(icon_view->priv->tip_window, TRUE);
+    gtk_widget_set_name(icon_view->priv->tip_window, "gtk-tooltips");
+    g_signal_connect(G_OBJECT(icon_view->priv->tip_window), "expose-event",
+                     G_CALLBACK(xfdesktop_icon_view_tip_window_expose),
+                     icon_view);
+    g_signal_connect(G_OBJECT(icon_view->priv->tip_window), 
"leave-notify-event",
+                     G_CALLBACK(xfdesktop_icon_view_tip_window_leave),
+                     icon_view);
+    
+    icon_view->priv->tip_label = gtk_label_new(NULL);
+    gtk_label_set_line_wrap(GTK_LABEL(icon_view->priv->tip_label), TRUE);
+    gtk_misc_set_alignment(GTK_MISC(icon_view->priv->tip_label), 0.5, 0.5);
+    gtk_widget_show(icon_view->priv->tip_label);
+    gtk_container_add(GTK_CONTAINER(icon_view->priv->tip_window),
+                      icon_view->priv->tip_label);
+}
+
+static gboolean
+xfdesktop_icon_view_show_tooltip(gpointer user_data)
+{
+    XfdesktopIconView *icon_view = user_data;
+    const gchar *tip_text;
+    GdkScreen *gscreen;
+    gint x, y, w, h, monitor_num;
+    GtkRequisition req;
+    GdkRectangle geom;
+    
+    icon_view->priv->tip_show_id = 0;
+    
+    if(!icon_view->priv->item_under_pointer
+       || icon_view->priv->definitely_dragging)
+    {
+        return FALSE;
+    }
+    
+    tip_text = 
xfdesktop_icon_peek_tooltip(icon_view->priv->item_under_pointer);
+    if(!tip_text)
+        return FALSE;
+    
+    xfdesktop_icon_view_ensure_tip_window(icon_view);
+    
+    gtk_label_set_text(GTK_LABEL(icon_view->priv->tip_label), tip_text);
+    
+    gtk_widget_size_request(icon_view->priv->tip_window, &req);
+    w = req.width;
+    h = req.height;
+    
+    gdk_display_get_pointer(gdk_display_get_default(), &gscreen, &x, &y,
+                            NULL);
+    monitor_num = gdk_screen_get_monitor_at_point(gscreen, x, y);
+    gdk_screen_get_monitor_geometry(gscreen, monitor_num, &geom);
+    gtk_window_set_screen(GTK_WINDOW(icon_view->priv->tip_window), gscreen);
+    
+    /* don't put the box directly under the mouse pointer, as this makes
+       dragging difficult */
+    ++x;
+    ++y;
+    
+    if(x + w > geom.x + geom.width)
+        x -= x + w - (geom.x + geom.width);
+    else if(x < geom.x)
+        x = geom.x;
+    
+    if(y + h > geom.y + geom.height)
+        y = geom.y + geom.height - h;
+    
+    gtk_window_move(GTK_WINDOW(icon_view->priv->tip_window), x, y);
+    gtk_widget_show(icon_view->priv->tip_window);
+    
+    return FALSE;
+}
+
+static gboolean
 xfdesktop_icon_view_motion_notify(GtkWidget *widget,
                                   GdkEventMotion *evt,
                                   gpointer user_data)
@@ -685,11 +836,15 @@
     {
         icon_view->priv->definitely_dragging = 
xfdesktop_icon_view_maybe_begin_drag(icon_view,
                                                                                
     evt);
-        if(icon_view->priv->definitely_dragging)
+        if(icon_view->priv->definitely_dragging) {
+            if(icon_view->priv->tip_window
+               && GTK_WIDGET_VISIBLE(icon_view->priv->tip_window))
+            {
+                gtk_widget_hide(icon_view->priv->tip_window);
+            }
             ret = TRUE;
-    }
-#ifdef HAVE_LIBEXO  /* no need to waste the CPU cycles otherwise... */
-    else {
+        }
+    } else {
         XfdesktopIcon *icon;
         GdkRectangle extents;
         
@@ -699,9 +854,21 @@
                || !xfdesktop_rectangle_contains_point(&extents, evt->x, 
evt->y))
             {
                 /* we're not over the icon anymore */
+                if(icon_view->priv->tip_window
+                   && GTK_WIDGET_VISIBLE(icon_view->priv->tip_window))
+                {
+                    gtk_widget_hide(icon_view->priv->tip_window);
+                }
+                if(icon_view->priv->tip_show_id) {
+                    g_source_remove(icon_view->priv->tip_show_id);
+                    icon_view->priv->tip_show_id = 0;
+                }
+                
                 icon = icon_view->priv->item_under_pointer;
                 icon_view->priv->item_under_pointer = NULL;
+#ifdef HAVE_LIBEXO
                 xfdesktop_icon_view_clear_icon_pixbuf_extents(icon_view, icon);
+#endif
             }
         } else {
             icon = xfdesktop_icon_view_widget_coords_to_item(icon_view,
@@ -710,12 +877,20 @@
             if(icon && xfdesktop_icon_get_extents(icon, &extents)
                && xfdesktop_rectangle_contains_point(&extents, evt->x, evt->y))
             {
+                if(icon != icon_view->priv->item_under_pointer) {
+                    /* show tip soon */
+                    icon_view->priv->tip_show_id = 
g_timeout_add(icon_view->priv->tip_timeout,
+                                                                 
xfdesktop_icon_view_show_tooltip,
+                                                                 icon_view);
+                }
+                
                 icon_view->priv->item_under_pointer = icon;
+#ifdef HAVE_LIBEXO
                 xfdesktop_icon_view_clear_icon_pixbuf_extents(icon_view, icon);
+#endif
             }
         }
     }
-#endif
     
     return ret;
 }
@@ -725,15 +900,31 @@
                                  GdkEventCrossing *evt,
                                  gpointer user_data)
 {
-#ifdef HAVE_LIBEXO  /* no need to waste the CPU cycles otherwise... */
     XfdesktopIconView *icon_view = XFDESKTOP_ICON_VIEW(user_data);
+    gboolean clear_icon = FALSE;
     
     if(icon_view->priv->item_under_pointer) {
-        XfdesktopIcon *icon = icon_view->priv->item_under_pointer;
-        icon_view->priv->item_under_pointer = NULL;
-        xfdesktop_icon_view_clear_icon_extents(icon_view, icon);
+        if(icon_view->priv->tip_window
+           && GTK_WIDGET_VISIBLE(icon_view->priv->tip_window))
+        {
+            GdkWindow *under_ptr = 
gdk_display_get_window_at_pointer(gdk_display_get_default(),
+                                                                     NULL,
+                                                                     NULL);
+            if(under_ptr != icon_view->priv->tip_window->window) {
+                gtk_widget_hide(icon_view->priv->tip_window);
+                clear_icon = TRUE;
+            }
+        } else
+            clear_icon = TRUE;
+        
+        if(clear_icon) {
+            XfdesktopIcon *icon = icon_view->priv->item_under_pointer;
+            icon_view->priv->item_under_pointer = NULL;
+#ifdef HAVE_LIBEXO
+            xfdesktop_icon_view_clear_icon_extents(icon_view, icon);
+#endif
+        }
     }
-#endif
     
     return FALSE;
 }

_______________________________________________
Xfce4-commits mailing list
[email protected]
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to