1998-11-01 Federico Mena Quintero <federico@nuclecu.unam.mx>

* gdesktop-icon.h (DesktopIcon): Added a child item for stippling
	the icon when it is selected.

	* gdesktop-icon.c (desktop_icon_select): Show/hide the stippling
	as appropriate.

	* gdesktop.c (desktop_icon_info_event): Handler for events on
	desktop icons.
	(select_icon): New function that handles icon selection based on
	mouse clicks and modifier keys.

	* gdesktop.c (struct desktop_icon_info): Added a type field to the
	structure.  It specifies the type of icon (file, directory), and
	is used to determine the DnD and menu behavior.
This commit is contained in:
Miguel de Icaza 1998-11-01 23:21:24 +00:00
parent 7de65931ef
commit 5fa467aa00
4 changed files with 204 additions and 1 deletions

View File

@ -1,3 +1,20 @@
1998-11-01 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gdesktop-icon.h (DesktopIcon): Added a child item for stippling
the icon when it is selected.
* gdesktop-icon.c (desktop_icon_select): Show/hide the stippling
as appropriate.
* gdesktop.c (desktop_icon_info_event): Handler for events on
desktop icons.
(select_icon): New function that handles icon selection based on
mouse clicks and modifier keys.
* gdesktop.c (struct desktop_icon_info): Added a type field to the
structure. It specifies the type of icon (file, directory), and
is used to determine the DnD and menu behavior.
1998-10-30 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gdesktop.c: We are now using the new desktop icon code. It is

View File

@ -15,6 +15,13 @@
#define SPACING 2
/* The 50% gray stipple for selected icons */
#define gray50_width 2
#define gray50_height 2
static char gray50_bits[] = {
0x02, 0x01, };
static void desktop_icon_class_init (DesktopIconClass *class);
static void desktop_icon_init (DesktopIcon *dicon);
static void desktop_icon_realize (GtkWidget *widget);
@ -88,6 +95,8 @@ canvas_size_allocated (GtkWidget *widget, GtkAllocation *allocation, gpointer da
static void
desktop_icon_init (DesktopIcon *dicon)
{
GdkBitmap *stipple;
/* Set the window policy */
gtk_window_set_policy (GTK_WINDOW (dicon), TRUE, TRUE, TRUE);
@ -119,6 +128,14 @@ desktop_icon_init (DesktopIcon *dicon)
gnome_icon_text_item_get_type (),
NULL);
stipple = gdk_bitmap_create_from_data (NULL, gray50_bits, gray50_width, gray50_height);
dicon->stipple = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (dicon->canvas)),
gnome_canvas_rect_get_type (),
"fill_stipple", stipple,
NULL);
gnome_canvas_item_hide (dicon->stipple);
gdk_bitmap_unref (stipple);
dicon->w_changed_id = gtk_signal_connect (GTK_OBJECT (dicon->text), "width_changed",
(GtkSignalFunc) size_changed,
dicon);
@ -130,9 +147,13 @@ desktop_icon_init (DesktopIcon *dicon)
static void
desktop_icon_realize (GtkWidget *widget)
{
DesktopIcon *dicon;
g_return_if_fail (widget != NULL);
g_return_if_fail (IS_DESKTOP_ICON (widget));
dicon = DESKTOP_ICON (widget);
if (GTK_WIDGET_CLASS (parent_class)->realize)
(* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
@ -150,6 +171,12 @@ desktop_icon_realize (GtkWidget *widget)
| WIN_HINTS_SKIP_WINLIST
| WIN_HINTS_SKIP_TASKBAR));
}
/* Set the stipple color now that we have a style */
gnome_canvas_item_set (dicon->stipple,
"fill_color_gdk", &widget->style->bg[GTK_STATE_SELECTED],
NULL);
}
/* Sets the icon from the specified image file. Does not re-create the window shape for the desktop
@ -385,6 +412,12 @@ desktop_icon_reshape (DesktopIcon *dicon)
"x", (dicon->width - icon_width) / 2.0,
"y", 0.0,
NULL);
gnome_canvas_item_set (dicon->stipple,
"x1", 0.0,
"y1", 0.0,
"x2", (double) dicon->width,
"y2", (double) icon_height,
NULL);
gnome_icon_text_item_setxy (GNOME_ICON_TEXT_ITEM (dicon->text), 0, icon_height + SPACING);
@ -393,3 +426,25 @@ desktop_icon_reshape (DesktopIcon *dicon)
gtk_widget_set_usize (GTK_WIDGET (dicon), dicon->width, dicon->height);
create_window_shape (dicon, icon_width, icon_height, text_width, text_height);
}
/**
* desktop_icon_select
* @dicon: The desktop icon which will be selected/unselected
* @sel: TRUE if icon should be selected, FALSE if it should be unselected
*
* Selects or unselects the icon. This means setting the selection flag of the icon text item as
* appropriate, and displaying the icon image as selected or not.
*/
void
desktop_icon_select (DesktopIcon *dicon, int sel)
{
g_return_if_fail (dicon != NULL);
g_return_if_fail (IS_DESKTOP_ICON (dicon));
if (sel)
gnome_canvas_item_show (dicon->stipple);
else
gnome_canvas_item_hide (dicon->stipple);
gnome_icon_text_item_select (GNOME_ICON_TEXT_ITEM (dicon->text), sel);
}

View File

@ -36,6 +36,7 @@ struct _DesktopIcon {
GnomeCanvasItem *icon; /* The item that contains the icon */
GnomeCanvasItem *text; /* The item that contains the editable text */
GnomeCanvasItem *stipple; /* The rectangle used as a stipple when the icon is selected */
int width, height; /* Total size of the window */
@ -63,6 +64,9 @@ void desktop_icon_set_text (DesktopIcon *dicon, char *text);
/* Makes the desktop icon reshape itself (for when the global desktop_use_shaped_icons flag changes) */
void desktop_icon_reshape (DesktopIcon *dicon);
/* Selects or unselects the icon based on the value of sel (TRUE is selected, FALSE is unselected) */
void desktop_icon_select (DesktopIcon *dicon, int sel);
END_GNOME_DECLS

View File

@ -20,11 +20,19 @@
#define DESKTOP_DIR_NAME "desktop"
/* Types of desktop icons */
enum icon_type {
ICON_FILE, /* Denotes a file (or symlink to a file) */
ICON_DIRECTORY /* Denotes a directory (or symlink to one) */
};
/* This structure defines the information carried by a desktop icon */
struct desktop_icon_info {
GtkWidget *dicon; /* The desktop icon widget */
int x, y; /* Position in the desktop */
char *filename; /* The file this icon refers to (relative to the desktop_directory) */
enum icon_type type; /* Type of icon, used to determine menu and DnD behavior */
int selected : 1; /* Is the icon selected? */
};
@ -152,6 +160,101 @@ desktop_icon_info_place (struct desktop_icon_info *dii, int auto_pos, int xpos,
gtk_widget_set_uposition (dii->dicon, xpos, ypos);
}
/* Unselects all the desktop icons */
static void
unselect_all (void)
{
GList *l;
struct desktop_icon_info *dii;
for (l = desktop_icons; l; l = l->next) {
dii = l->data;
if (dii->selected) {
desktop_icon_select (dii->dicon, FALSE);
dii->selected = FALSE;
}
}
}
/* Handles icon selection and unselection due to button presses */
static void
select_icon (struct desktop_icon_info *dii, GdkEventButton *event)
{
if (!(event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK))) {
/* Click on an unselected icon unselects everything and selects the icon */
unselect_all ();
desktop_icon_select (dii->dicon, TRUE);
dii->selected = TRUE;
} else if (event->state & GDK_SHIFT_MASK) {
; /* FIXME: handle range selection */
} else if (event->state & GDK_CONTROL_MASK) {
/* Control-click on an icon toggles its selected state */
desktop_icon_select (dii->dicon, !dii->selected);
dii->selected = !dii->selected;
}
}
/* Handler for events on desktop icons. The on_text flag specifies whether the event ocurred on the
* text item in the icon or not.
*/
static gint
desktop_icon_info_event (struct desktop_icon_info *dii, GdkEvent *event, int on_text)
{
int retval;
retval = FALSE;
switch (event->type) {
case GDK_BUTTON_PRESS:
if ((event->button.button == 1) && !(on_text && dii->selected)) {
select_icon (dii, (GdkEventButton *) event);
retval = TRUE;
} else if (event->button.button == 3)
retval = TRUE; /* FIXME: display menu */
break;
case GDK_2BUTTON_PRESS:
if (event->button.button != 1)
break;
/* FIXME: activate icon */
retval = TRUE;
break;
default:
break;
}
/* If we handled the event, do not pass it on to the icon text item */
if (on_text && retval)
gtk_signal_emit_stop_by_name (GTK_OBJECT (DESKTOP_ICON (dii->dicon)->text),
"event");
return retval;
}
/* Handler for button presses on the images on desktop icons. The desktop icon info structure is
* passed in the user data.
*/
static gint
icon_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
{
return desktop_icon_info_event (data, event, FALSE);
}
/* Handler for button presses on the text on desktop icons. The desktop icon info structure is
* passed in the user data.
*/
static gint
text_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
{
return desktop_icon_info_event (data, event, TRUE);
}
/* 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. It does not show the icon.
@ -162,20 +265,44 @@ desktop_icon_info_new (char *filename, int auto_pos, int xpos, int ypos)
struct desktop_icon_info *dii;
char *full_name;
char *icon_name;
struct stat s;
full_name = g_concat_dir_and_file (desktop_directory, filename);
if (mc_stat (full_name, &s) != 0) {
g_warning ("Could not stat %s; will not use a desktop icon", full_name);
g_free (full_name);
return NULL;
}
/* Create the icon structure */
icon_name = meta_get_icon_for_file (full_name);
dii = g_new (struct desktop_icon_info, 1);
dii->dicon = desktop_icon_new (icon_name, filename);
dii->filename = g_strdup (filename);
dii->type = S_ISDIR (s.st_mode) ? ICON_DIRECTORY : ICON_FILE;
dii->selected = FALSE;
g_free (full_name);
g_free (icon_name);
desktop_icon_info_place (dii, auto_pos, xpos, ypos);
/* Connect to the icon's signals */
gtk_signal_connect (GTK_OBJECT (DESKTOP_ICON (dii->dicon)->icon), "event",
(GtkSignalFunc) icon_event,
dii);
gtk_signal_connect (GTK_OBJECT (DESKTOP_ICON (dii->dicon)->text), "event",
(GtkSignalFunc) text_event,
dii);
gtk_signal_connect (GTK_OBJECT (DESKTOP_ICON (dii->dicon)->stipple), "event",
(GtkSignalFunc) icon_event,
dii);
/* Place the icon and append it to the list */
desktop_icon_info_place (dii, auto_pos, xpos, ypos);
desktop_icons = g_list_append (desktop_icons, dii);
return dii;