mirror of https://github.com/MidnightCommander/mc
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:
parent
7de65931ef
commit
5fa467aa00
|
@ -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>
|
1998-10-30 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||||
|
|
||||||
* gdesktop.c: We are now using the new desktop icon code. It is
|
* gdesktop.c: We are now using the new desktop icon code. It is
|
||||||
|
|
|
@ -15,6 +15,13 @@
|
||||||
#define SPACING 2
|
#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_class_init (DesktopIconClass *class);
|
||||||
static void desktop_icon_init (DesktopIcon *dicon);
|
static void desktop_icon_init (DesktopIcon *dicon);
|
||||||
static void desktop_icon_realize (GtkWidget *widget);
|
static void desktop_icon_realize (GtkWidget *widget);
|
||||||
|
@ -88,6 +95,8 @@ canvas_size_allocated (GtkWidget *widget, GtkAllocation *allocation, gpointer da
|
||||||
static void
|
static void
|
||||||
desktop_icon_init (DesktopIcon *dicon)
|
desktop_icon_init (DesktopIcon *dicon)
|
||||||
{
|
{
|
||||||
|
GdkBitmap *stipple;
|
||||||
|
|
||||||
/* Set the window policy */
|
/* Set the window policy */
|
||||||
|
|
||||||
gtk_window_set_policy (GTK_WINDOW (dicon), TRUE, TRUE, TRUE);
|
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 (),
|
gnome_icon_text_item_get_type (),
|
||||||
NULL);
|
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",
|
dicon->w_changed_id = gtk_signal_connect (GTK_OBJECT (dicon->text), "width_changed",
|
||||||
(GtkSignalFunc) size_changed,
|
(GtkSignalFunc) size_changed,
|
||||||
dicon);
|
dicon);
|
||||||
|
@ -130,9 +147,13 @@ desktop_icon_init (DesktopIcon *dicon)
|
||||||
static void
|
static void
|
||||||
desktop_icon_realize (GtkWidget *widget)
|
desktop_icon_realize (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
|
DesktopIcon *dicon;
|
||||||
|
|
||||||
g_return_if_fail (widget != NULL);
|
g_return_if_fail (widget != NULL);
|
||||||
g_return_if_fail (IS_DESKTOP_ICON (widget));
|
g_return_if_fail (IS_DESKTOP_ICON (widget));
|
||||||
|
|
||||||
|
dicon = DESKTOP_ICON (widget);
|
||||||
|
|
||||||
if (GTK_WIDGET_CLASS (parent_class)->realize)
|
if (GTK_WIDGET_CLASS (parent_class)->realize)
|
||||||
(* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
|
(* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
|
||||||
|
|
||||||
|
@ -150,6 +171,12 @@ desktop_icon_realize (GtkWidget *widget)
|
||||||
| WIN_HINTS_SKIP_WINLIST
|
| WIN_HINTS_SKIP_WINLIST
|
||||||
| WIN_HINTS_SKIP_TASKBAR));
|
| 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
|
/* 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,
|
"x", (dicon->width - icon_width) / 2.0,
|
||||||
"y", 0.0,
|
"y", 0.0,
|
||||||
NULL);
|
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);
|
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);
|
gtk_widget_set_usize (GTK_WIDGET (dicon), dicon->width, dicon->height);
|
||||||
create_window_shape (dicon, icon_width, icon_height, text_width, text_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);
|
||||||
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ struct _DesktopIcon {
|
||||||
|
|
||||||
GnomeCanvasItem *icon; /* The item that contains the icon */
|
GnomeCanvasItem *icon; /* The item that contains the icon */
|
||||||
GnomeCanvasItem *text; /* The item that contains the editable text */
|
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 */
|
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) */
|
/* Makes the desktop icon reshape itself (for when the global desktop_use_shaped_icons flag changes) */
|
||||||
void desktop_icon_reshape (DesktopIcon *dicon);
|
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
|
END_GNOME_DECLS
|
||||||
|
|
||||||
|
|
129
gnome/gdesktop.c
129
gnome/gdesktop.c
|
@ -20,11 +20,19 @@
|
||||||
#define DESKTOP_DIR_NAME "desktop"
|
#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 */
|
/* This structure defines the information carried by a desktop icon */
|
||||||
struct desktop_icon_info {
|
struct desktop_icon_info {
|
||||||
GtkWidget *dicon; /* The desktop icon widget */
|
GtkWidget *dicon; /* The desktop icon widget */
|
||||||
int x, y; /* Position in the desktop */
|
int x, y; /* Position in the desktop */
|
||||||
char *filename; /* The file this icon refers to (relative to the desktop_directory) */
|
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? */
|
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);
|
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.
|
/* 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,
|
* 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.
|
* 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;
|
struct desktop_icon_info *dii;
|
||||||
char *full_name;
|
char *full_name;
|
||||||
char *icon_name;
|
char *icon_name;
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
full_name = g_concat_dir_and_file (desktop_directory, filename);
|
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);
|
icon_name = meta_get_icon_for_file (full_name);
|
||||||
|
|
||||||
dii = g_new (struct desktop_icon_info, 1);
|
dii = g_new (struct desktop_icon_info, 1);
|
||||||
dii->dicon = desktop_icon_new (icon_name, filename);
|
dii->dicon = desktop_icon_new (icon_name, filename);
|
||||||
dii->filename = g_strdup (filename);
|
dii->filename = g_strdup (filename);
|
||||||
|
dii->type = S_ISDIR (s.st_mode) ? ICON_DIRECTORY : ICON_FILE;
|
||||||
dii->selected = FALSE;
|
dii->selected = FALSE;
|
||||||
|
|
||||||
g_free (full_name);
|
g_free (full_name);
|
||||||
g_free (icon_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);
|
desktop_icons = g_list_append (desktop_icons, dii);
|
||||||
|
|
||||||
return dii;
|
return dii;
|
||||||
|
|
Loading…
Reference in New Issue