From e7911e2b1540d1fe9d3e6dac717e4eda0c2862ae Mon Sep 17 00:00:00 2001 From: Miguel de Icaza Date: Thu, 22 Oct 1998 00:32:21 +0000 Subject: [PATCH] Sync sync - debugging time - Federico 1998-10-21 Federico Mena Quintero * gdesktop.c (create_desktop_icon): Renamed from my_create_transparent_text_window. Now uses the DesktopIcon widget for its work. (get_desktop_icon_for_dentry): Renamed from get_transparent_window_for_dentry. Uses the DesktopIcon widget. (get_desktop_icon_for_di): Renamed from get_transparent_window_for_di. (desktop_icon_properties): Do not size_request the icon, since now we can get its dimensions directly from the DesktopIcon structure. * desktop-icon.[ch]: New file that takes care of desktop icons. It provides the spiffy widget that is used for them. * Makefile.in: Added desktop-icon.[ch] to the list of sources. MC should use Automake, I think. --- gnome/ChangeLog | 18 +++++ gnome/Makefile.in | 3 + gnome/gdesktop-icon.c | 155 ++++++++++++++++++++++++++++++++++++++---- gnome/gdesktop-icon.h | 9 ++- gnome/gdesktop.c | 113 ++++++++++++++---------------- gnome/gdesktop.h | 1 - gnome/gtrans.c | 2 + 7 files changed, 226 insertions(+), 75 deletions(-) diff --git a/gnome/ChangeLog b/gnome/ChangeLog index dd3934fd1..72a0653cd 100644 --- a/gnome/ChangeLog +++ b/gnome/ChangeLog @@ -1,3 +1,21 @@ +1998-10-21 Federico Mena Quintero + + * gdesktop.c (create_desktop_icon): Renamed from + my_create_transparent_text_window. Now uses the DesktopIcon + widget for its work. + (get_desktop_icon_for_dentry): Renamed from + get_transparent_window_for_dentry. Uses the DesktopIcon widget. + (get_desktop_icon_for_di): Renamed from + get_transparent_window_for_di. + (desktop_icon_properties): Do not size_request the icon, since now + we can get its dimensions directly from the DesktopIcon structure. + + * desktop-icon.[ch]: New file that takes care of desktop icons. + It provides the spiffy widget that is used for them. + + * Makefile.in: Added desktop-icon.[ch] to the list of sources. + MC should use Automake, I think. + 1998-10-21 Miguel de Icaza * gscreen.c (panel_create_icon_display): Small size adjustment. diff --git a/gnome/Makefile.in b/gnome/Makefile.in index b8d7b880e..926457086 100644 --- a/gnome/Makefile.in +++ b/gnome/Makefile.in @@ -15,6 +15,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ GNOMESRCS = \ + desktop-icon.c \ gkey.c \ gmain.c \ gscreen.c \ @@ -37,6 +38,7 @@ GNOMESRCS = \ gblist.c GNOMEHDRS = \ + desktop-icon.h \ gmain.h \ gscreen.h \ gwidget.h \ @@ -77,6 +79,7 @@ OOBJS = main.o dlg.o screen.o widget.o wtools.o info.o boxes.o \ option.o cmd.o utilunix.o popt.o xslint.o OBJS = $(LOBJS) $(OOBJS) \ + desktop-icon.o \ gkey.o \ gmain.o \ gscreen.o \ diff --git a/gnome/gdesktop-icon.c b/gnome/gdesktop-icon.c index 9c6a278c5..bf02a01bb 100644 --- a/gnome/gdesktop-icon.c +++ b/gnome/gdesktop-icon.c @@ -6,10 +6,15 @@ */ #include +#include #include "desktop-icon.h" #include "gdesktop.h" +/* Spacing between icon and text */ +#define SPACING 2 + + static void desktop_icon_class_init (DesktopIconClass *class); static void desktop_icon_init (DesktopIcon *dicon); @@ -46,12 +51,117 @@ desktop_icon_class_init (DesktopIconClass *class) GtkObjectClass *object_class; GtkWidgetClass *widget_class; - objct_class = (GtkObjectClass *) class; + object_class = (GtkObjectClass *) class; widget_class = (GtkWidgetClass *) class; parent_class = gtk_type_class (gtk_window_get_type ()); } +/* Computes and sets a new window shape for the desktop icon */ +static void +create_window_shape (DesktopIcon *dicon, int icon_width, int icon_height, int text_width, int text_height) +{ + GdkBitmap *mask; + GdkBitmap *im_mask; + GdkGC *mgc; + GdkColor c; + + /* Create the initial mask and clear it */ + + mask = gdk_pixmap_new (GTK_WIDGET (dicon)->window, dicon->width, dicon->height, 1); + + mgc = gdk_gc_new (mask); + c.pixel = 0; + gdk_gc_set_foreground (mgc, &c); + gdk_draw_rectangle (mask, mgc, TRUE, 0, 0, dicon->width, dicon->height); + + /* Paint the mask of the image */ + + c.pixel = 1; + gdk_gc_set_foreground (mgc, &c); + + im_mask = GNOME_CANVAS_IMAGE (dicon->icon)->mask; + + if (im_mask) + gdk_draw_pixmap (mask, + mgc, + im_mask, + 0, 0, + (dicon->width - icon_width) / 2, 0, + icon_width, icon_height); + else + gdk_draw_rectangle (mask, mgc, TRUE, + (dicon->width - icon_width) / 2, 0, + icon_width, icon_height); + + /* Fill the area for the text */ + + gdk_draw_rectangle (mask, mgc, TRUE, + (dicon->width - text_width) / 2, + icon_height + SPACING, + text_width, text_height); + + gtk_widget_shape_combine_mask (GTK_WIDGET (dicon), mask, 0, 0); + gdk_pixmap_unref (mask); + gdk_gc_unref (mgc); +} + +/* Resets the positions of the desktop icon's child items and recomputes the window's shape mask */ +static void +reshape (DesktopIcon *dicon) +{ + GtkArg args[2]; + int icon_width, icon_height; + double x1, y1, x2, y2; + int text_width, text_height; + + /* Get size of icon image */ + + args[0].name = "width"; + args[1].name = "height"; + gtk_object_getv (GTK_OBJECT (dicon->icon), 2, args); + icon_width = GTK_VALUE_DOUBLE (args[0]); + icon_height = GTK_VALUE_DOUBLE (args[0]); + + /* Get size of icon text */ + + gnome_canvas_item_get_bounds (dicon->text, &x1, &y1, &x2, &y2); + text_width = x2 - x1; + text_height = y2 - y1; + + /* Calculate new size of widget */ + + dicon->width = MAX (icon_width, text_width); + dicon->height = icon_height + SPACING + text_height; + + /* Set new position of children */ + + gnome_canvas_item_set (dicon->icon, + "x", (dicon->width - icon_width) / 2.0, + "y", 0.0, + NULL); + + gnome_icon_text_item_setxy (GNOME_ICON_TEXT_ITEM (dicon->text), + (dicon->width - text_width) / 2, + icon_height + SPACING); + + /* Create and set the window shape */ + + gtk_widget_set_usize (GTK_WIDGET (dicon), dicon->width, dicon->height); + create_window_shape (dicon, icon_width, icon_height, text_width, text_height); +} + +/* Callback used when the size of the icon text item changes */ +static void +size_changed (GnomeIconTextItem *text, gpointer data) +{ + DesktopIcon *dicon; + + dicon = DESKTOP_ICON (data); + + reshape (dicon); +} + static void desktop_icon_init (DesktopIcon *dicon) { @@ -70,14 +180,20 @@ desktop_icon_init (DesktopIcon *dicon) /* Create the icon and the text items */ - dicon->icon = gnome_canvas_item_new (gnome_canvas_root (dicon->canvas), + dicon->icon = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (dicon->canvas)), gnome_canvas_image_get_type (), "anchor", GTK_ANCHOR_NW, NULL); - dicon->text = gnome_canvas_item_new (gnome_canvas_root (dicon->canvas), + dicon->text = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (dicon->canvas)), gnome_icon_text_item_get_type (), NULL); + dicon->w_changed_id = gtk_signal_connect (GTK_OBJECT (dicon->text), "width_changed", + (GtkSignalFunc) size_changed, + dicon); + dicon->h_changed_id = gtk_signal_connect (GTK_OBJECT (dicon->text), "height_changed", + (GtkSignalFunc) size_changed, + dicon); } GtkWidget * @@ -96,13 +212,6 @@ desktop_icon_new (char *image_file, char *text) return GTK_WIDGET (dicon); } -/* Resets the positions of the desktop icon's child items and recomputes the window's shape mask */ -static void -reshape (DesktopIcon *dicon) -{ - /* FIXME */ -} - void desktop_icon_set_icon (DesktopIcon *dicon, char *image_file) { @@ -125,12 +234,14 @@ desktop_icon_set_icon (DesktopIcon *dicon, char *image_file) /* Destroy the old image if it exists */ arg.name = "image"; - gtk_object_getv (GTK_OBJECT (dicon), 1, &arg); + gtk_object_getv (GTK_OBJECT (dicon->icon), 1, &arg); old_im = GTK_VALUE_POINTER (arg); gnome_canvas_item_set (dicon->icon, "image", im, + "width", (double) im->rgb_width, + "height", (double) im->rgb_height, NULL); if (old_im) @@ -142,9 +253,29 @@ desktop_icon_set_icon (DesktopIcon *dicon, char *image_file) void desktop_icon_set_text (DesktopIcon *dicon, char *text) { + GtkArg arg; + int icon_width; + g_return_if_fail (dicon != NULL); g_return_if_fail (IS_DESKTOP_ICON (dicon)); g_return_if_fail (text != NULL); - /* FIXME */ + arg.name = "width"; + gtk_object_getv (GTK_OBJECT (dicon->icon), 1, &arg); + icon_width = GTK_VALUE_DOUBLE (arg); + + gtk_signal_handler_block (GTK_OBJECT (dicon->text), dicon->w_changed_id); + gtk_signal_handler_block (GTK_OBJECT (dicon->text), dicon->h_changed_id); + + gnome_icon_text_item_configure (GNOME_ICON_TEXT_ITEM (dicon->text), + 0, 0, + MAX (SNAP_X, icon_width), + DESKTOP_ICON_FONT, + text, + TRUE); + + gtk_signal_handler_unblock (GTK_OBJECT (dicon->text), dicon->w_changed_id); + gtk_signal_handler_unblock (GTK_OBJECT (dicon->text), dicon->h_changed_id); + + reshape (dicon); } diff --git a/gnome/gdesktop-icon.h b/gnome/gdesktop-icon.h index e3b2074ec..0a4a6b625 100644 --- a/gnome/gdesktop-icon.h +++ b/gnome/gdesktop-icon.h @@ -10,11 +10,15 @@ #include #include +#include #include BEGIN_GNOME_DECLS +#define DESKTOP_ICON_FONT "-*-helvetica-medium-r-normal--10-*-*-*-p-*-*-*" + + #define TYPE_DESKTOP_ICON (desktop_icon_get_type ()) #define DESKTOP_ICON(obj) (GTK_CHECK_CAST ((obj), TYPE_DESKTOP_ICON, DesktopIcon)) #define DESKTOP_ICON_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_DESKTOP_ICON, DesktopIconClass)) @@ -33,7 +37,10 @@ struct _DesktopIcon { GnomeCanvasItem *icon; /* The item that contains the icon */ GnomeCanvasItem *text; /* The item that contains the editable text */ - int width, height; /* Size of the window */ + int width, height; /* Total size of the window */ + + int w_changed_id; /* Signal connection ID for "width_changed" from the icon text item */ + int h_changed_id; /* Signal connection ID for "height_changed" from the icon text item */ }; struct _DesktopIconClass { diff --git a/gnome/gdesktop.c b/gnome/gdesktop.c index b18827dda..3947262aa 100644 --- a/gnome/gdesktop.c +++ b/gnome/gdesktop.c @@ -5,10 +5,10 @@ * Author: Miguel de Icaza (miguel@gnu.org) */ #include -#include "fs.h" #include -#include "util.h" +#include "desktop-icon.h" #include "gdesktop.h" +#include "fs.h" #include "../vfs/vfs.h" #include #include "mad.h" @@ -125,18 +125,23 @@ snap_to (desktop_icon_t *di, int absolute, int x, int y) static void get_icon_screen_x_y (desktop_icon_t *di, int *x, int *y) { + int w, h; + + w = DESKTOP_ICON (di->widget)->width; + h = DESKTOP_ICON (di->widget)->height; + if (di->grid_x != -1){ *x = di->grid_x * SNAP_X; *y = di->grid_y * SNAP_Y; - *x = *x + (SNAP_X - di->widget->requisition.width)/2; + *x = *x + (SNAP_X - w) / 2; if (*x < 0) *x = 0; - if (di->widget->requisition.height > SNAP_Y) - *y = *y + (SNAP_Y - di->widget->requisition.height)/2; + if (h > SNAP_Y) + *y = *y + (SNAP_Y - h) / 2; else - *y = *y + (SNAP_Y - di->widget->requisition.height); + *y = *y + (SNAP_Y - h); } else { *x = di->x; *y = di->y; @@ -961,51 +966,38 @@ desktop_icon_delete (GtkWidget *widget, desktop_icon_t *di) desktop_icon_remove (di); } -static void -lower_window(GtkWidget *widget) -{ - /* Note: Lowering the window has the problem of getting into a loop of - * flashing bitmaps on the desktop. Do not enable this feature - */ - /* gdk_window_lower(widget->window); */ - -} - GtkWidget * -my_create_transparent_text_window (char *file, char *text) +create_desktop_icon (char *file, char *text) { GtkWidget *w; - int events = GDK_BUTTON_PRESS_MASK | GDK_BUTTON1_MOTION_MASK | GDK_EXPOSURE_MASK; - - w = create_transparent_text_window (file, text, events); - if (!w){ - static char *default_pix; - if (!default_pix){ - default_pix = gnome_unconditional_pixmap_file ("launcher-program.png"); - } - w = create_transparent_text_window (default_pix, text, events); - if (!w) - return NULL; + if (g_file_exists (file)) + w = desktop_icon_new (file, text); + else { + static char *default_image; + + if (!default_image) + default_image = gnome_unconditional_pixmap_file ("launcher-program.png"); + + if (g_file_exists (default_image)) + w = desktop_icon_new (default_image, text); + else + w = NULL; } -#if 0 - /* Useless, really, we need to use the WM hints */ - gtk_signal_connect(GTK_OBJECT(w), "expose_event", - lower_window, NULL); -#endif + return w; } static GtkWidget * -get_transparent_window_for_dentry (GnomeDesktopEntry *dentry) +get_desktop_icon_for_dentry (GnomeDesktopEntry *dentry) { - GtkWidget *window; + GtkWidget *dicon; char *icon_label; icon_label = dentry->name ? dentry->name : x_basename (dentry->exec[0]); if (dentry->icon) - window = my_create_transparent_text_window (dentry->icon, icon_label); + dicon = create_desktop_icon (dentry->icon, icon_label); else { static char *default_icon_path; static char exists; @@ -1017,18 +1009,18 @@ get_transparent_window_for_dentry (GnomeDesktopEntry *dentry) } if (exists) - window = my_create_transparent_text_window (default_icon_path, icon_label); + dicon = create_desktop_icon (default_icon_path, icon_label); else { - window = gtk_window_new (GTK_WINDOW_POPUP); - gtk_widget_set_usize (window, 20, 20); + dicon = gtk_window_new (GTK_WINDOW_POPUP); + gtk_widget_set_usize (dicon, 20, 20); } } - return window; + return dicon; } static GtkWidget * -get_transparent_window_for_di (desktop_icon_t *di) +get_desktop_icon_for_di (desktop_icon_t *di) { GtkWidget *window; char *icon_label, *icon; @@ -1036,7 +1028,7 @@ get_transparent_window_for_di (desktop_icon_t *di) icon_label = x_basename (di->pathname); icon = get_desktop_icon (di->pathname); - window = my_create_transparent_text_window (icon, icon_label); + window = create_desktop_icon (icon, icon_label); g_free (icon); return window; } @@ -1101,18 +1093,17 @@ desktop_icon_properties (GtkWidget *widget, desktop_icon_t *di) gtk_widget_destroy (di->widget); if (di->dentry) - di->widget = get_transparent_window_for_dentry (di->dentry); + di->widget = get_desktop_icon_for_dentry (di->dentry); else - di->widget = get_transparent_window_for_di (di); + di->widget = get_desktop_icon_for_di (di); - if (icons_snap_to_grid && di->grid_x != -1){ - gtk_widget_size_request (di->widget, &di->widget->requisition); + if (icons_snap_to_grid && di->grid_x != -1) get_icon_screen_x_y (di, &di->x, &di->y); - } + gtk_widget_set_uposition (di->widget, di->x, di->y); - + post_setup_desktop_icon (di, 1); - + if (di->dentry) gnome_desktop_entry_save (di->dentry); } @@ -1135,17 +1126,17 @@ char *root_drop_types [] = { static void desktop_load_from_dentry (GnomeDesktopEntry *dentry) { - GtkWidget *window; + GtkWidget *dicon; desktop_icon_t *di; - window = get_transparent_window_for_dentry (dentry); + dicon = get_desktop_icon_for_dentry (dentry); - if (!window) + if (!dicon) return; di = xmalloc (sizeof (desktop_icon_t), "desktop_load_entry"); di->dentry = dentry; - di->widget = window; + di->widget = dicon; di->pathname = dentry->location; desktop_icons = g_list_prepend (desktop_icons, di); @@ -1269,7 +1260,7 @@ static void desktop_create_launch_entry (char *desktop_file, char *pathname, char *short_name, GdkPoint **pos) { GnomeDesktopEntry *dentry; - GtkWidget *window; + GtkWidget *dicon; desktop_icon_t *di; char *icon; struct stat s; @@ -1293,14 +1284,14 @@ desktop_create_launch_entry (char *desktop_file, char *pathname, char *short_nam gnome_desktop_entry_save (dentry); desktop_load_from_dentry (dentry); #if 0 - window = my_create_transparent_text_window (icon, x_basename (pathname)); + dicon = create_desktop_icon (icon, x_basename (pathname)); g_free (icon); - if (!window) + if (!dicon) return; di = xmalloc (sizeof (desktop_icon_t), "dcle"); di->dentry = NULL; - di->widget = window; + di->widget = dicon; di->pathname = strdup (pathname); desktop_icon_set_position (di); @@ -1309,13 +1300,13 @@ desktop_create_launch_entry (char *desktop_file, char *pathname, char *short_nam desktop_icons = g_list_prepend (desktop_icons, (gpointer) di); /* Double clicking executes the command, single clicking brings up context menu */ - gtk_signal_connect (GTK_OBJECT (window), "button_press_event", GTK_SIGNAL_FUNC (desktop_file_exec), di); - gtk_widget_realize (window); + gtk_signal_connect (GTK_OBJECT (dicon), "button_press_event", GTK_SIGNAL_FUNC (desktop_file_exec), di); + gtk_widget_realize (dicon); - gtk_signal_connect (GTK_OBJECT (window), "drop_data_available_event", + gtk_signal_connect (GTK_OBJECT (dicon), "drop_data_available_event", GTK_SIGNAL_FUNC (drop_on_launch_entry), di); - gtk_widget_dnd_drop_set (window, TRUE, drop_types, ELEMENTS (drop_types), FALSE); + gtk_widget_dnd_drop_set (dicon, TRUE, drop_types, ELEMENTS (drop_types), FALSE); #endif } diff --git a/gnome/gdesktop.h b/gnome/gdesktop.h index 657a837b2..8afe25943 100644 --- a/gnome/gdesktop.h +++ b/gnome/gdesktop.h @@ -47,7 +47,6 @@ typedef struct { extern int want_transparent_icons; extern int want_transparent_text; -GtkWidget *create_transparent_text_window (char *file, char *text, int extra_events); GtkWidget *make_transparent_window (char *file); /* gdesktop.c */ diff --git a/gnome/gtrans.c b/gnome/gtrans.c index 3c6e012bd..cfe69eb59 100644 --- a/gnome/gtrans.c +++ b/gnome/gtrans.c @@ -18,6 +18,7 @@ int want_transparent_icons = 1; int want_transparent_text = 0; +#if 0 static void set_window_text (GtkWidget *window, GdkImlibImage *im, char *text) { @@ -228,6 +229,7 @@ create_transparent_text_window (char *file, char *text, int extra_events) #endif return win; } +#endif GtkWidget * make_transparent_window (char *file)