1998-12-03 Federico Mena Quintero <federico@nuclecu.unam.mx>

* gdesktop.c (load_desktop_icons): Added arguments that specify
	where to place the newly-created icons.  This needs some tweaking still.
	(reload_desktop_icons): Now takes arguments for the position of
	the new icons.
	(drag_data_received): Pass in the drop position to reload_desktop_icons().

	* gscreen.c (panel_tree_drag_motion): Added missing variable declaration.

	* gdesktop.c (load_desktop_icons): Added an incremental flag that
	specifies whether icon creation is unconditional regardless of
	whether there is an icon for a file or not.
	(reload_desktop_icons): Use the incremental flag in load_desktop_icons().
	(drag_data_received): Reload the desktop incrementally, to avoid flicker.
	(desktop_icon_info_new): Use mc_lstat(), not mc_stat().  We do
	want to read symlinks, even dangling ones, if they exist.
	(load_desktop_icons): While we are reading the desktop directory,
	first place all the icons that have their metadata icon-position
	set, and build a list of the ones that don't.  *Then* place
	those.  This fixes overlapping icons on weird situations.

	* directory.xpm: Removed bogus garbage.  There was a stale pixmap here.

	* gdesktop.c (setup_desktop_dnd): Allow for GDK_ACTION_ASK as well.

	* gscreen.c (panel_widget_motion): The action argument to
	gtk_drag_begin() is a mask of possible actions, not a single action.

	* gdesktop.c (drag_data_received): Only reload the icons if the
	drop was successful.
This commit is contained in:
Miguel de Icaza 1998-12-04 02:08:06 +00:00
parent 8366acf5cd
commit 2eab3ff5f6
4 changed files with 122 additions and 165 deletions

View File

@ -1,15 +1,47 @@
1998-12-03 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gdesktop.c (load_desktop_icons): Added arguments that specify
where to place the newly-created icons. This needs some tweaking still.
(reload_desktop_icons): Now takes arguments for the position of
the new icons.
(drag_data_received): Pass in the drop position to reload_desktop_icons().
* gscreen.c (panel_tree_drag_motion): Added missing variable declaration.
* gdesktop.c (load_desktop_icons): Added an incremental flag that
specifies whether icon creation is unconditional regardless of
whether there is an icon for a file or not.
(reload_desktop_icons): Use the incremental flag in load_desktop_icons().
(drag_data_received): Reload the desktop incrementally, to avoid flicker.
(desktop_icon_info_new): Use mc_lstat(), not mc_stat(). We do
want to read symlinks, even dangling ones, if they exist.
(load_desktop_icons): While we are reading the desktop directory,
first place all the icons that have their metadata icon-position
set, and build a list of the ones that don't. *Then* place
those. This fixes overlapping icons on weird situations.
* directory.xpm: Removed bogus garbage. There was a stale pixmap here.
* gdesktop.c (setup_desktop_dnd): Allow for GDK_ACTION_ASK as well.
* gscreen.c (panel_widget_motion): The action argument to
gtk_drag_begin() is a mask of possible actions, not a single action.
* gdesktop.c (drag_data_received): Only reload the icons if the
drop was successful.
1998-12-03 Jonathan Blandford <jrb@redhat.com>
* gdialogs.c (create_op_win): starting the op_win dialog stuff
1998-12-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
* gscreen.c (panel_create_icon_display, panel_create_file_list):
Hook up to drag_begin and drag_end events.
* gscreen.c (panel_tree_drag_motion): Improve interactivity
(x_create_panel): Add a little decorating frame.
(panel_create_icon_display, panel_create_file_list):
Hook up to drag_begin and drag_end events.

View File

@ -1,120 +1,4 @@
/* XPM */
static char * xpm_new[] = {
"24 24 89 1",
" c None",
". c #000000",
"+ c #ADAD9C",
"@ c #959585",
"# c #DCDCC5",
"$ c #DFDFC8",
"% c #242424",
"& c #A7A796",
"* c #D7D7C1",
"= c #D9D9C3",
"- c #DCDCC4",
"; c #DDDDC7",
"> c #E1E1CA",
", c #A6A694",
"' c #D6D6BF",
") c #D8D8C2",
"! c #DBDBC4",
"~ c #DFDFC7",
"{ c #E3E3CB",
"] c #B2B29F",
"^ c #7C7C7C",
"/ c #646464",
"( c #D5D5BD",
"_ c #D5D5BF",
": c #D7D7C0",
"< c #DADAC3",
"[ c #DEDEC6",
"} c #E1E1C9",
"| c #E5E5CD",
"1 c #E9E9D1",
"2 c #343434",
"3 c #E7E7E7",
"4 c #373736",
"5 c #B8B8A6",
"6 c #D3D3BC",
"7 c #D9D9C2",
"8 c #DDDDC5",
"9 c #E0E0C8",
"0 c #E8E8D0",
"a c #ECECD4",
"b c #EEEED5",
"c c #ECECEC",
"d c #EDEDED",
"e c #3D3D37",
"f c #CECEB7",
"g c #E6E6CE",
"h c #EAEAD2",
"i c #F1F1D8",
"j c #A5A594",
"k c #EEEEE5",
"l c #3C3C3C",
"m c #8F8F80",
"n c #D0D0B9",
"o c #E4E4CB",
"p c #EAEAD1",
"q c #ECECD3",
"r c #EFEFD6",
"s c #F2F2D9",
"t c #F3F3DA",
"u c #EEEEE6",
"v c #505050",
"w c #929282",
"x c #D1D1B9",
"y c #E7E7CF",
"z c #EBEBD2",
"A c #F4F4DB",
"B c #F5F5DC",
"C c #969686",
"D c #D2D2BC",
"E c #E0E0C9",
"F c #E9E9D0",
"G c #EDEDD4",
"H c #F0F0D7",
"I c #BEBEAB",
"J c #797973",
"K c #D8D8C1",
"L c #DDDDC6",
"M c #98988F",
"N c #E4E4CC",
"O c #818174",
"P c #E2E2CA",
"Q c #BEBEAE",
"R c #4E4E4E",
"S c #828274",
"T c #EBEBD3",
"U c #BBBBA8",
"V c #CDCDB8",
"W c #4D4D45",
"X c #A6A696",
" ",
" ",
" . ",
" ..+. ",
" ..@#$% ",
" ..&*=-;>. ",
" ..,'**)!~{]. ",
" .^/'(_:<[}|12 ",
" .3456*789|0ab. ",
" .cdef_!9g0hbij. ",
" .kklmn9opqrist. ",
" .uvwx-}yzbittAB. ",
" ..CD!E{FGHtAABBI. ",
" .JK7L>ypbitBBBBB). ",
" .M!#$NyzbitBBBBBO. ",
" .~9P|1qrsABBBB.. ",
" .Q||0hGHtABB<. ",
" R01hGrstAsS. ",
" .TaGriss<. ",
" .rHis1j. ",
" .UstVW. ",
" .tX. ",
" .. ",
" "};
/* XPM */
static char * directory_xpm[] = {
"16 13 5 1",
" c None",

View File

@ -95,10 +95,10 @@ static GtkTargetEntry dnd_targets[] = {
static int dnd_ntargets = sizeof (dnd_targets) / sizeof (dnd_targets[0]);
/* Proxy window for DnD on the root window */
static GtkWidget *dnd_proxy_window;
/* 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.
@ -492,7 +492,7 @@ desktop_icon_info_new (char *filename, int auto_pos, int xpos, int ypos)
full_name = g_concat_dir_and_file (desktop_directory, filename);
if (mc_stat (full_name, &s) != 0) {
if (mc_lstat (full_name, &s) != 0) {
g_warning ("Could not stat %s; will not use a desktop icon", full_name);
g_free (full_name);
return NULL;
@ -598,17 +598,37 @@ create_desktop_dir (void)
}
}
/* Reads the ~/Desktop directory and creates the initial desktop icons */
/* Returns TRUE if there is already an icon in the desktop for the specified filename, FALSE otherwise. */
static int
icon_exists (char *filename)
{
int i;
GList *l;
struct desktop_icon_info *dii;
for (i = 0; i < (layout_cols * layout_rows); i++)
for (l = layout_slots[i].icons; l; l = l->next) {
dii = l->data;
if (strcmp (filename, dii->filename) == 0)
return TRUE;
}
return FALSE;
}
/* Reads the ~/Desktop directory and creates the desktop icons. If incremental is TRUE, then an
* icon will not be created for a file if there is already an icon for it, and icons will be created
* starting at the specified position.
*/
static void
load_desktop_icons (void)
load_desktop_icons (int incremental, int xpos, int ypos)
{
struct dirent *dirent;
DIR *dir;
char *full_name;
int have_pos, x, y;
int i;
GList *l;
struct desktop_icon_info *dii;
GSList *need_position_list, *l;
dir = mc_opendir (desktop_directory);
if (!dir) {
@ -619,28 +639,48 @@ load_desktop_icons (void)
return;
}
/* First create the icons for all the files that do have their icon position set. Build a
* list of the icons that do not have their position set.
*/
need_position_list = NULL;
while ((dirent = mc_readdir (dir)) != NULL) {
if (((dirent->d_name[0] == '.') && (dirent->d_name[1] == 0))
|| ((dirent->d_name[0] == '.') && (dirent->d_name[1] == '.') && (dirent->d_name[2] == 0)))
continue;
if (incremental && icon_exists (dirent->d_name))
continue;
full_name = g_concat_dir_and_file (desktop_directory, dirent->d_name);
have_pos = gmeta_get_icon_pos (full_name, &x, &y);
desktop_icon_info_new (dirent->d_name, !have_pos, x, y);
if (have_pos) {
dii = desktop_icon_info_new (dirent->d_name, FALSE, x, y);
gtk_widget_show (dii->dicon);
g_free (full_name);
} else
need_position_list = g_slist_prepend (need_position_list, g_strdup (dirent->d_name));
}
mc_closedir (dir);
/* Show all the icons */
/* Now create the icons for all the files that did not have their position set. This makes
* auto-placement work correctly without overlapping icons.
*/
for (i = 0; i < (layout_cols * layout_rows); i++)
for (l = layout_slots[i].icons; l; l = l->next) {
dii = l->data;
need_position_list = g_slist_reverse (need_position_list);
for (l = need_position_list; l; l = l->next) {
dii = desktop_icon_info_new (l->data, FALSE, xpos, ypos);
gtk_widget_show (dii->dicon);
g_free (l->data);
}
g_slist_free (need_position_list);
}
/* Destroys all the current desktop icons */
@ -663,12 +703,16 @@ destroy_desktop_icons (void)
}
}
/* Reloads the desktop icons */
/* Reloads the desktop icons. If incremental is TRUE, then the existing icons will not be destroyed
* first, and the new icons will be put at the specified position.
*/
static void
reload_desktop_icons (void)
reload_desktop_icons (int incremental, int x, int y)
{
if (!incremental)
destroy_desktop_icons ();
load_desktop_icons ();
load_desktop_icons (incremental, x, y);
}
/* Sets up a proxy window for DnD on the specified X window. Courtesy of Owen Taylor */
@ -764,15 +808,25 @@ static void
drag_data_received (GtkWidget *widget, GdkDragContext *context, gint x, gint y,
GtkSelectionData *data, guint info, guint time, gpointer user_data)
{
int retval;
gint dx, dy;
switch (info) {
case TARGET_URI_LIST:
printf ("uri-list dropped on desktop!\n");
/* Fix the proxy window offsets */
gdk_window_get_position (widget->window, &dx, &dy);
x += dx;
y += dy;
gdnd_drop_on_directory (context, data, desktop_directory);
reload_desktop_icons (); /* FIXME: this is inefficient and it sucks! */
/* Drop! */
retval = gdnd_drop_on_directory (context, data, desktop_directory);
if (retval)
reload_desktop_icons (TRUE, x, y);
/* FIXME: return TRUE for delete if appropriate */
gtk_drag_finish (context, TRUE, FALSE, time);
gtk_drag_finish (context, retval, FALSE, time);
return;
default:
@ -793,9 +847,9 @@ setup_desktop_dnd (void)
g_warning ("Eeeeek, some moron is already taking drops on the root window!");
gtk_drag_dest_set (dnd_proxy_window,
GTK_DEST_DEFAULT_DROP,
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
dnd_targets, dnd_ntargets,
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK);
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);
gtk_signal_connect (GTK_OBJECT (dnd_proxy_window), "drag_data_received",
GTK_SIGNAL_FUNC (drag_data_received), NULL);
@ -812,7 +866,7 @@ desktop_init (void)
{
create_layout_info ();
create_desktop_dir ();
load_desktop_icons ();
load_desktop_icons (FALSE, 0, 0);
setup_desktop_dnd ();
}

View File

@ -15,8 +15,9 @@
#include "mad.h"
#include "x.h"
#include "dir.h"
#include "panel.h"
#include "command.h"
#include "panel.h"
#define WANT_WIDGETS /* bleah */
#include "main.h"
#include "color.h"
#include "mouse.h"
@ -60,11 +61,6 @@ static GdkImlibImage *icon_view_regular;
static GdkImlibImage *icon_view_core;
static GdkImlibImage *icon_view_sock;
#ifdef OLD_DND
static char *drag_types [] = { "text/plain", "file:ALL", "url:ALL" };
static char *drop_types [] = { "url:ALL" };
#endif
static GtkTargetEntry drag_types [] = {
{ "text/uri-list", 0, TARGET_URI_LIST },
{ "text/plain", 0, TARGET_TEXT_PLAIN }
@ -1061,13 +1057,10 @@ panel_clist_button_release (GtkWidget *widget, GdkEventButton *event, WPanel *pa
return FALSE;
}
#define MAX(a,b) ((a > b) ? a : b)
static int
panel_widget_motion (GtkWidget *widget, GdkEventMotion *event, WPanel *panel)
{
GtkTargetList *list;
GdkDragAction action;
GdkDragContext *context;
if (!panel->maybe_start_drag)
@ -1082,15 +1075,9 @@ panel_widget_motion (GtkWidget *widget, GdkEventMotion *event, WPanel *panel)
list = gtk_target_list_new (drag_types, ELEMENTS (drag_types));
/* Control+Shift = LINK */
if ((event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) == (GDK_SHIFT_MASK | GDK_CONTROL_MASK))
action = GDK_ACTION_LINK;
else if (event->state & (GDK_SHIFT_MASK))
action = GDK_ACTION_MOVE;
else
action = GDK_ACTION_COPY;
context = gtk_drag_begin (widget, list, action, panel->maybe_start_drag, (GdkEvent *) event);
context = gtk_drag_begin (widget, list,
GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK,
panel->maybe_start_drag, (GdkEvent *) event);
gtk_drag_set_icon_default (context);
return FALSE;