diff --git a/gnome/ChangeLog b/gnome/ChangeLog index 56a5825cd..b29a1e7f5 100644 --- a/gnome/ChangeLog +++ b/gnome/ChangeLog @@ -1,3 +1,15 @@ +1998-10-30 Federico Mena Quintero + + * gdesktop.c: We are now using the new desktop icon code. It is + not yet complete, but what is there does work. We have icon + creation, auto-layout and snapping. Next step is drag and drop + and popup menus. + + * glayout.c: #ifdef out the stuff that uses the old desktop code. + I will replace it gradually. + * gmain.c: Likewise. + * gscreen.c: Likewise. + 1998-10-27 Miguel de Icaza * gscreen.c (panel_icon_list_button_release): Remove unused diff --git a/gnome/gdesktop-icon.c b/gnome/gdesktop-icon.c index 38de6047e..62db171b7 100644 --- a/gnome/gdesktop-icon.c +++ b/gnome/gdesktop-icon.c @@ -118,7 +118,7 @@ desktop_icon_init (DesktopIcon *dicon) dicon->text = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (dicon->canvas)), gnome_icon_text_item_get_type (), NULL); - gnome_icon_text_item_select (GNOME_ICON_TEXT_ITEM (dicon->text), TRUE); + dicon->w_changed_id = gtk_signal_connect (GTK_OBJECT (dicon->text), "width_changed", (GtkSignalFunc) size_changed, dicon); @@ -203,7 +203,7 @@ set_text (DesktopIcon *dicon, char *text) gnome_icon_text_item_configure (GNOME_ICON_TEXT_ITEM (dicon->text), 0, icon_height + SPACING, -#if 0 +#if 1 DESKTOP_SNAP_X, #else SNAP_X, @@ -306,7 +306,7 @@ create_window_shape (DesktopIcon *dicon, int icon_width, int icon_height, int te im = GNOME_CANVAS_IMAGE (dicon->icon)->im; gdk_imlib_render (im, icon_width, icon_height); im_mask = gdk_imlib_move_mask (im); -#if 0 +#if 1 if (im_mask && desktop_use_shaped_icons) { #else if (im_mask && want_transparent_icons) { @@ -372,7 +372,7 @@ desktop_icon_reshape (DesktopIcon *dicon) text_height = y2 - y1 + 1; /* Calculate new size of widget */ -#if 0 +#if 1 dicon->width = MAX (icon_width, DESKTOP_SNAP_X); #else dicon->width = MAX (icon_width, SNAP_X); diff --git a/gnome/gdesktop.c b/gnome/gdesktop.c index cbe284890..efd984750 100644 --- a/gnome/gdesktop.c +++ b/gnome/gdesktop.c @@ -5,11 +5,14 @@ * Authors: Federico Mena * Miguel de Icaza */ -#if 0 +#if 1 #include #include +#include "dialog.h" #include "gdesktop.h" +#include "gdesktop-icon.h" #include "gmetadata.h" +#include "fs.h" #include "../vfs/vfs.h" @@ -35,14 +38,92 @@ int desktop_snap_icons = FALSE; /* The computed name of the user's desktop directory */ static char *desktop_directory; -/* Layout information: number of rows/columns for the layout slots, and the array of slots */ +/* Layout information: number of rows/columns for the layout slots, and the array of slots. Each + * slot is an integer that specifies the number of icons that belong to that slot. + */ static int layout_cols; static int layout_rows; static int *layout_slots; -/* The list of desktop icons */ +/* The list of desktop icons (desktop_icon_info structures) */ static GList *desktop_icons; +#define l_slots(x, y) (layout_slots[(x) * layout_rows + (y)]) + + +/* Looks for a free slot in the layout_slots array and returns the coordinates that coorespond to + * it. "Free" means it either has zero icons in it, or it has the minimum number of icons of all + * the slots. + */ +static void +get_icon_auto_pos (int *x, int *y) +{ + int min, min_x, min_y; + int u, v; + int val; + + min = l_slots (0, 0); + min_x = min_y = 0; + + for (u = 0; u < layout_cols; u++) + for (v = 0; v < layout_rows; v++) { + val = l_slots (u, v); + + if (val == 0) { + /* Optimization: if it is zero, return immediately */ + + *x = u * DESKTOP_SNAP_X; + *y = v * DESKTOP_SNAP_Y; + return; + } else if (val < min) { + min = val; + min_x = u; + min_y = v; + } + } + + *x = min_x * DESKTOP_SNAP_X; + *y = min_y * DESKTOP_SNAP_Y; +} + +/* Snaps the specified position to the icon grid. It looks for the closest free spot on the grid, + * or the closest one that has the least number of icons in it. + */ +static void +get_icon_snap_pos (int *x, int *y) +{ + int min, min_x, min_y; + int min_dist; + int sx, sy; + int u, v; + int val, dist; + int dx, dy; + + min = l_slots (0, 0); + min_x = min_y = 0; + min_dist = INT_MAX; + + sx = DESKTOP_SNAP_X * (*x / DESKTOP_SNAP_X); + sy = DESKTOP_SNAP_Y * (*y / DESKTOP_SNAP_Y); + + for (u = 0; u < layout_cols; u++) + for (v = 0; v < layout_rows; v++) { + val = l_slots (u, v); + + dx = sx - u; + dy = sy - v; + dist = dx * dx + dy * dy; + + if (((val == min) && (dist < min_dist)) || (val < min)) { + min_dist = dist; + min_x = u; + min_y = v; + } + } + + *x = min_x * DESKTOP_SNAP_X; + *y = min_y * DESKTOP_SNAP_Y; +} /* Places a desktop icon. If auto_pos is true, then the function will look for a place to position * the icon automatically, else it will use the specified coordinates, snapped to the grid if the @@ -51,14 +132,31 @@ static GList *desktop_icons; static void desktop_icon_info_place (struct desktop_icon_info *dii, int auto_pos, int xpos, int ypos) { - /* FIXME */ + int u, v; + + if (auto_pos) + get_icon_auto_pos (&xpos, &ypos); + else if (desktop_snap_icons) + get_icon_snap_pos (&xpos, &ypos); + + /* Increase the number of icons in the corresponding slot */ + + u = xpos / DESKTOP_SNAP_X; + v = ypos / DESKTOP_SNAP_Y; + l_slots (u, v)++; + + /* Move the icon */ + + dii->x = xpos; + dii->y = ypos; + gtk_widget_set_uposition (dii->dicon, xpos, ypos); } /* Creates a new desktop icon. The filename is the pruned filename inside the desktop directory. * If auto_pos is true, then the function will look for a place to position the icon automatically, - * else it will use the specified coordinates. + * else it will use the specified coordinates. It does not show the icon. */ -static void +static struct desktop_icon_info * desktop_icon_info_new (char *filename, int auto_pos, int xpos, int ypos) { struct desktop_icon_info *dii; @@ -69,7 +167,7 @@ desktop_icon_info_new (char *filename, int auto_pos, int xpos, int ypos) icon_name = meta_get_icon_for_file (full_name); dii = g_new (struct desktop_icon_info, 1); - dii->widget = desktop_icon_new (icon_name, filename); + dii->dicon = desktop_icon_new (icon_name, filename); dii->filename = g_strdup (filename); dii->selected = FALSE; @@ -77,15 +175,39 @@ desktop_icon_info_new (char *filename, int auto_pos, int xpos, int ypos) g_free (icon_name); desktop_icon_info_place (dii, auto_pos, xpos, ypos); - gtk_widget_show (dii->dicon); + + desktop_icons = g_list_append (desktop_icons, dii); + + return dii; +} + +/* Frees a desktop icon information structure, and destroy the icon widget. Does not remove the + * structure from the desktop_icons list! + */ +static void +desktop_icon_info_free (struct desktop_icon_info *dii) +{ + int u, v; + + gtk_widget_destroy (dii->dicon); + + /* Decrease the number of icons in the corresponding slot */ + + u = dii->x / DESKTOP_SNAP_X; + v = dii->y / DESKTOP_SNAP_Y; + l_slots (u, v)--; + g_assert (l_slots (u, v) >= 0); + + g_free (dii->filename); + g_free (dii); } /* Creates the layout information array */ static void create_layout_info (void) { - layout_cols = gdk_screen_width () / DESKTOP_SNAP_X; - layout_rows = gdk_screen_height () / DESKTOP_SNAP_Y; + layout_cols = (gdk_screen_width () + DESKTOP_SNAP_X - 1) / DESKTOP_SNAP_X; + layout_rows = (gdk_screen_height () + DESKTOP_SNAP_Y - 1) / DESKTOP_SNAP_Y; layout_slots = g_new0 (int, layout_cols * layout_rows); } @@ -129,6 +251,8 @@ load_initial_desktop_icons (void) DIR *dir; char *full_name; int have_pos, x, y; + GList *list; + struct desktop_icon_info *dii; dir = mc_opendir (desktop_directory); if (!dir) { @@ -147,12 +271,19 @@ load_initial_desktop_icons (void) full_name = g_concat_dir_and_file (desktop_directory, dirent->d_name); have_pos = meta_get_icon_pos (full_name, &x, &y); - desktop_icon_info_new (dirent->d_name, have_pos, x, y); + desktop_icon_info_new (dirent->d_name, !have_pos, x, y); g_free (full_name); } mc_closedir (dir); + + /* Show all the icons */ + + for (list = desktop_icons; list; list = list->next) { + dii = list->data; + gtk_widget_show (dii->dicon); + } } /** @@ -181,7 +312,7 @@ desktop_destroy (void) /* Destroy the desktop icons */ for (list = desktop_icons; list; list = list->next) - desktop_icon_info_free (dii->data); + desktop_icon_info_free (list->data); g_list_free (desktop_icons); desktop_icons = NULL; diff --git a/gnome/gdesktop.h b/gnome/gdesktop.h index 99e5a3daf..d648af4e7 100644 --- a/gnome/gdesktop.h +++ b/gnome/gdesktop.h @@ -9,7 +9,7 @@ #ifndef GDESKTOP_H #define GDESKTOP_H -#if 0 +#if 1 /* Snap granularity for desktop icons -- maybe these should be calculated in terms of the font size? */ @@ -35,6 +35,32 @@ void desktop_destroy (void); + + + + + +enum { + TARGET_URI_LIST, + TARGET_URL_LIST, + TARGET_TEXT_PLAIN, +}; +typedef enum { + application, + directory, + file +} icon_t; +/* A structure that describes each icon on the desktop */ +typedef struct { + GnomeDesktopEntry *dentry; + GtkWidget *widget; + icon_t type; + int x, y; + int grid_x, grid_y; + char *pathname; +} desktop_icon_t; +GtkWidget *make_transparent_window (char *file); + #else #define MC_LIB_DESKTOP "mc.desktop" diff --git a/gnome/glayout.c b/gnome/glayout.c index f839dac2c..8e7f28401 100644 --- a/gnome/glayout.c +++ b/gnome/glayout.c @@ -329,7 +329,9 @@ GnomeUIInfo gnome_panel_commands_menu [] = { }; GnomeUIInfo gnome_panel_desktop_menu [] = { +#if 0 { GNOME_APP_UI_ITEM, N_("_Arrange icons"), N_("Arranges the icons on the desktop"), gnome_arrange_icons }, +#endif /* { GNOME_APP_UI_TOGGLEITEM, N_("Desktop grid"), N_("Use a grid for laying out icons"), gnome_toggle_snap }, */ { GNOME_APP_UI_ENDOFINFO, 0, 0 } }; diff --git a/gnome/gmain.c b/gnome/gmain.c index 1cdc51395..d60358ac7 100644 --- a/gnome/gmain.c +++ b/gnome/gmain.c @@ -504,8 +504,11 @@ create_panels (void) GList *p, *g; char *geo; WPanel *panel; - +#if 1 + desktop_init (); +#else start_desktop (); +#endif cmdline = command_new (0, 0, 0); the_hint = label_new (0, 0, 0, NULL); @@ -539,7 +542,11 @@ create_panels (void) run_dlg (desktop_dlg); /* shutdown gnome specific bits of midnight commander */ +#if 1 + desktop_destroy (); +#else stop_desktop (); +#endif } static void diff --git a/gnome/gscreen.c b/gnome/gscreen.c index d360d2ba7..3a549b7fb 100644 --- a/gnome/gscreen.c +++ b/gnome/gscreen.c @@ -533,10 +533,14 @@ static struct { context_menu_callback callback; } file_actions [] = { { N_("Properties"), F_SINGLE | F_PANEL, (context_menu_callback) panel_action_properties }, +#if 0 { N_("Properties"), F_SINGLE | F_DICON, (context_menu_callback) desktop_icon_properties }, +#endif { "", F_SINGLE, NULL }, { N_("Open"), F_PANEL | F_ALL, (context_menu_callback) panel_action_open }, +#if 0 { N_("Open"), F_DICON | F_ALL, (context_menu_callback) desktop_icon_execute }, +#endif { N_("Open with"), F_PANEL | F_ALL, (context_menu_callback) panel_action_open_with }, { N_("View"), F_PANEL | F_NOTDIR, (context_menu_callback) panel_action_view }, { N_("View unfiltered"), F_PANEL | F_NOTDIR, (context_menu_callback) panel_action_view_unfiltered }, @@ -564,7 +568,9 @@ common_menu_t common_panel_actions [] = { }; common_menu_t common_dicon_actions [] = { +#if 0 { N_("Delete"), (context_menu_callback) desktop_icon_delete }, +#endif { NULL, NULL } }; @@ -1065,7 +1071,9 @@ panel_icon_list_drag_data_received (GtkWidget *widget, else dir = g_strdup (panel->cwd); } +#if 0 drop_on_directory (selection_data, context, context->suggested_action, dir, 0); +#endif free (dir); update_one_panel_widget (panel, 0, UP_KEEPSEL); @@ -1104,7 +1112,9 @@ panel_clist_drag_data_received (GtkWidget *widget, else dir = g_strdup (panel->cwd); } +#if 0 drop_on_directory (selection_data, context, context->suggested_action, dir, 0); +#endif free (dir); update_one_panel_widget (panel, 0, UP_KEEPSEL); @@ -1234,7 +1244,9 @@ panel_clist_drop_data_available (GtkWidget *widget, GdkEventDropDataAvailable *d g_assert (row < panel->count); } +#if 0 drop_on_directory (data, drop_dir, 0); +#endif if (drop_dir != panel->cwd) free (drop_dir); @@ -1586,7 +1598,9 @@ panel_icon_list_drop_data_available (GtkWidget *widget, GdkEventDropDataAvailabl else drop_dir = panel->cwd; } +#if 0 drop_on_directory (data, drop_dir, 0); +#endif if (drop_dir != panel->cwd) free (drop_dir);