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>
|
||||
|
||||
* gdesktop.c: We are now using the new desktop icon code. It is
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
129
gnome/gdesktop.c
129
gnome/gdesktop.c
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue