1999-04-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
* gtkflist.[ch]: New files. This is a "file list" widget derived from GtkCList that does several things: - Overrides all mouse and keyboard event handlers. - Implements its own, *sane* selection behavior, unlike GtkCList's, which is broken. - Implements the same selection behavior as the desktop, which is a) correct, and b) consistent. * gscreen.c (panel_create_file_list): Use the GtkFList widget. (panel_widget_motion): Changed the drag thresholds to be the same as in gtkdnd.c. (start_drag): New convenience function to begin a drag operation. (panel_widget_motion): Use start_drag(). (panel_clist_scrolling_is_desirable): Offsets must be with respect to the clist_window, not to the allocation. (panel_clist_drag_motion): Normalize the y coordinate of the motion event to the clist_window. * gdesktop.c (desktop_icon_info_destroy): Reset the last_selected_icon to NULL if it is destroyed. * Makefile.in: Added gtkflist to the list of files.
Этот коммит содержится в:
родитель
a372e9a375
Коммит
cdeefae1ec
@ -1,3 +1,31 @@
|
|||||||
|
1999-04-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
|
||||||
|
|
||||||
|
* gtkflist.[ch]: New files. This is a "file list" widget derived
|
||||||
|
from GtkCList that does several things:
|
||||||
|
|
||||||
|
- Overrides all mouse and keyboard event handlers.
|
||||||
|
|
||||||
|
- Implements its own, *sane* selection behavior, unlike
|
||||||
|
GtkCList's, which is broken.
|
||||||
|
|
||||||
|
- Implements the same selection behavior as the desktop,
|
||||||
|
which is a) correct, and b) consistent.
|
||||||
|
|
||||||
|
* gscreen.c (panel_create_file_list): Use the GtkFList widget.
|
||||||
|
(panel_widget_motion): Changed the drag thresholds to be the same
|
||||||
|
as in gtkdnd.c.
|
||||||
|
(start_drag): New convenience function to begin a drag operation.
|
||||||
|
(panel_widget_motion): Use start_drag().
|
||||||
|
(panel_clist_scrolling_is_desirable): Offsets must be with respect
|
||||||
|
to the clist_window, not to the allocation.
|
||||||
|
(panel_clist_drag_motion): Normalize the y coordinate of the
|
||||||
|
motion event to the clist_window.
|
||||||
|
|
||||||
|
* gdesktop.c (desktop_icon_info_destroy): Reset the
|
||||||
|
last_selected_icon to NULL if it is destroyed.
|
||||||
|
|
||||||
|
* Makefile.in: Added gtkflist to the list of files.
|
||||||
|
|
||||||
1999-04-09 Rosanna Yuen <rwsy@mit.edu>
|
1999-04-09 Rosanna Yuen <rwsy@mit.edu>
|
||||||
|
|
||||||
* gaction.c (gmc_view): We now have consistant actions everywhere;
|
* gaction.c (gmc_view): We now have consistant actions everywhere;
|
||||||
|
@ -60,6 +60,7 @@ GNOMESRCS = \
|
|||||||
gsession.c \
|
gsession.c \
|
||||||
gtools.c \
|
gtools.c \
|
||||||
gtkdtree.c \
|
gtkdtree.c \
|
||||||
|
gtkflist.c \
|
||||||
gtree.c \
|
gtree.c \
|
||||||
gutil.c \
|
gutil.c \
|
||||||
gview.c \
|
gview.c \
|
||||||
@ -91,6 +92,7 @@ GNOMEHDRS = \
|
|||||||
gscreen.h \
|
gscreen.h \
|
||||||
gsession.h \
|
gsession.h \
|
||||||
gtkdtree.h \
|
gtkdtree.h \
|
||||||
|
gtkflist.h \
|
||||||
gtree.h \
|
gtree.h \
|
||||||
gwidget.h
|
gwidget.h
|
||||||
|
|
||||||
@ -172,6 +174,7 @@ OBJS = \
|
|||||||
gutil.o \
|
gutil.o \
|
||||||
gview.o \
|
gview.o \
|
||||||
gtkdtree.o \
|
gtkdtree.o \
|
||||||
|
gtkflist.o \
|
||||||
gwidget.o
|
gwidget.o
|
||||||
|
|
||||||
NORMALOBJS = \
|
NORMALOBJS = \
|
||||||
|
259
gnome/gdesktop.c
259
gnome/gdesktop.c
@ -303,6 +303,9 @@ desktop_icon_info_place (DesktopIconInfo *dii, int xpos, int ypos)
|
|||||||
static void
|
static void
|
||||||
desktop_icon_info_destroy (DesktopIconInfo *dii)
|
desktop_icon_info_destroy (DesktopIconInfo *dii)
|
||||||
{
|
{
|
||||||
|
if (last_selected_icon == dii)
|
||||||
|
last_selected_icon = NULL;
|
||||||
|
|
||||||
gtk_widget_destroy (dii->dicon);
|
gtk_widget_destroy (dii->dicon);
|
||||||
remove_from_slot (dii);
|
remove_from_slot (dii);
|
||||||
|
|
||||||
@ -1102,6 +1105,134 @@ try_to_mount (char *filename, file_entry *fe)
|
|||||||
return do_mount_umount (filename, TRUE);
|
return do_mount_umount (filename, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is a HORRIBLE HACK. It creates a temporary panel structure for gpopup's
|
||||||
|
* perusal. Once gmc is rewritten, all file lists including panels will be a
|
||||||
|
* single data structure, and the world will be happy again.
|
||||||
|
*/
|
||||||
|
static WPanel *
|
||||||
|
create_panel_from_desktop (void)
|
||||||
|
{
|
||||||
|
WPanel *panel;
|
||||||
|
int nicons, count;
|
||||||
|
int marked_count, dir_marked_count;
|
||||||
|
long total;
|
||||||
|
int selected_index;
|
||||||
|
int i;
|
||||||
|
file_entry *fe;
|
||||||
|
GList *l;
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
panel = g_new0 (WPanel, 1);
|
||||||
|
|
||||||
|
/* Count the number of desktop icons */
|
||||||
|
|
||||||
|
nicons = 0;
|
||||||
|
for (i = 0; i < layout_cols * layout_rows; i++)
|
||||||
|
nicons += layout_slots[i].num_icons;
|
||||||
|
|
||||||
|
/* Create the file entry list */
|
||||||
|
|
||||||
|
panel->dir.size = nicons;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
marked_count = 0;
|
||||||
|
dir_marked_count = 0;
|
||||||
|
total = 0;
|
||||||
|
selected_index = -1;
|
||||||
|
|
||||||
|
if (nicons != 0) {
|
||||||
|
panel->dir.list = g_new (file_entry, nicons);
|
||||||
|
|
||||||
|
fe = panel->dir.list;
|
||||||
|
|
||||||
|
for (i = 0; i < layout_cols * layout_rows; i++)
|
||||||
|
for (l = layout_slots[i].icons; l; l = l->next) {
|
||||||
|
DesktopIconInfo *dii;
|
||||||
|
char *full_name;
|
||||||
|
|
||||||
|
dii = l->data;
|
||||||
|
full_name = g_concat_dir_and_file (desktop_directory, dii->filename);
|
||||||
|
if (mc_lstat (full_name, &s) == -1) {
|
||||||
|
g_warning ("Could not stat %s, bad things will happen",
|
||||||
|
full_name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_entry_fill (fe, &s, full_name);
|
||||||
|
if (dii->selected) {
|
||||||
|
marked_count++;
|
||||||
|
fe->f.marked = TRUE;
|
||||||
|
|
||||||
|
if (S_ISDIR (fe->buf.st_mode)) {
|
||||||
|
dir_marked_count++;
|
||||||
|
if (fe->f.dir_size_computed)
|
||||||
|
total += fe->buf.st_size;
|
||||||
|
} else
|
||||||
|
total += fe->buf.st_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (full_name);
|
||||||
|
fe++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill the rest of the panel structure */
|
||||||
|
|
||||||
|
panel->list_type = list_icons;
|
||||||
|
strncpy (panel->cwd, desktop_directory, sizeof (panel->cwd));
|
||||||
|
panel->count = count; /* the actual number of lstat()ed files */
|
||||||
|
panel->marked = marked_count;
|
||||||
|
panel->dirs_marked = dir_marked_count;
|
||||||
|
panel->total = total;
|
||||||
|
panel->selected = selected_index;
|
||||||
|
panel->is_a_desktop_panel = TRUE;
|
||||||
|
panel->id = -1;
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pushes our hacked-up desktop panel into the containers list */
|
||||||
|
WPanel *
|
||||||
|
push_desktop_panel_hack (void)
|
||||||
|
{
|
||||||
|
WPanel *panel;
|
||||||
|
PanelContainer *container;
|
||||||
|
|
||||||
|
panel = create_panel_from_desktop ();
|
||||||
|
container = g_new (PanelContainer, 1);
|
||||||
|
container->splitted = FALSE;
|
||||||
|
container->panel = panel;
|
||||||
|
|
||||||
|
containers = g_list_append (containers, container);
|
||||||
|
|
||||||
|
if (!current_panel_ptr)
|
||||||
|
current_panel_ptr = container;
|
||||||
|
else if (!other_panel_ptr)
|
||||||
|
other_panel_ptr = container;
|
||||||
|
|
||||||
|
/* Set it as the current panel and invoke the menu */
|
||||||
|
|
||||||
|
set_current_panel (panel);
|
||||||
|
mc_chdir (desktop_directory);
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Frees our hacked-up panel created in the function above */
|
||||||
|
static void
|
||||||
|
free_panel_from_desktop (WPanel *panel)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < panel->count; i++)
|
||||||
|
g_free (panel->dir.list[i].fname);
|
||||||
|
|
||||||
|
if (panel->dir.list)
|
||||||
|
g_free (panel->dir.list);
|
||||||
|
|
||||||
|
g_free (panel);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* desktop_icon_info_open:
|
* desktop_icon_info_open:
|
||||||
* @dii: The desktop icon to open.
|
* @dii: The desktop icon to open.
|
||||||
@ -1264,134 +1395,6 @@ desktop_icon_info_get_by_filename (char *filename)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is a HORRIBLE HACK. It creates a temporary panel structure for gpopup's
|
|
||||||
* perusal. Once gmc is rewritten, all file lists including panels will be a
|
|
||||||
* single data structure, and the world will be happy again.
|
|
||||||
*/
|
|
||||||
static WPanel *
|
|
||||||
create_panel_from_desktop (void)
|
|
||||||
{
|
|
||||||
WPanel *panel;
|
|
||||||
int nicons, count;
|
|
||||||
int marked_count, dir_marked_count;
|
|
||||||
long total;
|
|
||||||
int selected_index;
|
|
||||||
int i;
|
|
||||||
file_entry *fe;
|
|
||||||
GList *l;
|
|
||||||
struct stat s;
|
|
||||||
|
|
||||||
panel = g_new0 (WPanel, 1);
|
|
||||||
|
|
||||||
/* Count the number of desktop icons */
|
|
||||||
|
|
||||||
nicons = 0;
|
|
||||||
for (i = 0; i < layout_cols * layout_rows; i++)
|
|
||||||
nicons += layout_slots[i].num_icons;
|
|
||||||
|
|
||||||
/* Create the file entry list */
|
|
||||||
|
|
||||||
panel->dir.size = nicons;
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
marked_count = 0;
|
|
||||||
dir_marked_count = 0;
|
|
||||||
total = 0;
|
|
||||||
selected_index = -1;
|
|
||||||
|
|
||||||
if (nicons != 0) {
|
|
||||||
panel->dir.list = g_new (file_entry, nicons);
|
|
||||||
|
|
||||||
fe = panel->dir.list;
|
|
||||||
|
|
||||||
for (i = 0; i < layout_cols * layout_rows; i++)
|
|
||||||
for (l = layout_slots[i].icons; l; l = l->next) {
|
|
||||||
DesktopIconInfo *dii;
|
|
||||||
char *full_name;
|
|
||||||
|
|
||||||
dii = l->data;
|
|
||||||
full_name = g_concat_dir_and_file (desktop_directory, dii->filename);
|
|
||||||
if (mc_lstat (full_name, &s) == -1) {
|
|
||||||
g_warning ("Could not stat %s, bad things will happen",
|
|
||||||
full_name);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
file_entry_fill (fe, &s, full_name);
|
|
||||||
if (dii->selected) {
|
|
||||||
marked_count++;
|
|
||||||
fe->f.marked = TRUE;
|
|
||||||
|
|
||||||
if (S_ISDIR (fe->buf.st_mode)) {
|
|
||||||
dir_marked_count++;
|
|
||||||
if (fe->f.dir_size_computed)
|
|
||||||
total += fe->buf.st_size;
|
|
||||||
} else
|
|
||||||
total += fe->buf.st_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (full_name);
|
|
||||||
fe++;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill the rest of the panel structure */
|
|
||||||
|
|
||||||
panel->list_type = list_icons;
|
|
||||||
strncpy (panel->cwd, desktop_directory, sizeof (panel->cwd));
|
|
||||||
panel->count = count; /* the actual number of lstat()ed files */
|
|
||||||
panel->marked = marked_count;
|
|
||||||
panel->dirs_marked = dir_marked_count;
|
|
||||||
panel->total = total;
|
|
||||||
panel->selected = selected_index;
|
|
||||||
panel->is_a_desktop_panel = TRUE;
|
|
||||||
panel->id = -1;
|
|
||||||
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
WPanel *
|
|
||||||
push_desktop_panel_hack (void)
|
|
||||||
{
|
|
||||||
WPanel *panel;
|
|
||||||
PanelContainer *container;
|
|
||||||
|
|
||||||
panel = create_panel_from_desktop ();
|
|
||||||
container = g_new (PanelContainer, 1);
|
|
||||||
container->splitted = FALSE;
|
|
||||||
container->panel = panel;
|
|
||||||
|
|
||||||
containers = g_list_append (containers, container);
|
|
||||||
|
|
||||||
if (!current_panel_ptr)
|
|
||||||
current_panel_ptr = container;
|
|
||||||
else if (!other_panel_ptr)
|
|
||||||
other_panel_ptr = container;
|
|
||||||
|
|
||||||
/* Set it as the current panel and invoke the menu */
|
|
||||||
|
|
||||||
set_current_panel (panel);
|
|
||||||
mc_chdir (desktop_directory);
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Frees our hacked-up panel created in the function above */
|
|
||||||
static void
|
|
||||||
free_panel_from_desktop (WPanel *panel)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < panel->count; i++)
|
|
||||||
g_free (panel->dir.list[i].fname);
|
|
||||||
|
|
||||||
if (panel->dir.list)
|
|
||||||
g_free (panel->dir.list);
|
|
||||||
|
|
||||||
g_free (panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Used to execute the popup menu for desktop icons */
|
/* Used to execute the popup menu for desktop icons */
|
||||||
static void
|
static void
|
||||||
do_popup_menu (DesktopIconInfo *dii, GdkEventButton *event)
|
do_popup_menu (DesktopIconInfo *dii, GdkEventButton *event)
|
||||||
|
282
gnome/gscreen.c
282
gnome/gscreen.c
@ -34,6 +34,7 @@
|
|||||||
#include "gcmd.h"
|
#include "gcmd.h"
|
||||||
#include "gcliplabel.h"
|
#include "gcliplabel.h"
|
||||||
#include "gicon.h"
|
#include "gicon.h"
|
||||||
|
#include "gtkflist.h"
|
||||||
#include "../vfs/vfs.h"
|
#include "../vfs/vfs.h"
|
||||||
#include <gdk/gdkprivate.h>
|
#include <gdk/gdkprivate.h>
|
||||||
|
|
||||||
@ -467,70 +468,33 @@ panel_file_list_configure_contents (GtkWidget *sw, WPanel *panel, int main_width
|
|||||||
gtk_clist_thaw (clist);
|
gtk_clist_thaw (clist);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
/* Handler for the select_row signal of the clist. We synchronize the panel's
|
||||||
panel_file_list_press_row (GtkWidget *file_list, GdkEvent *event, WPanel *panel)
|
* idea of a selection, and handle pending actions that the
|
||||||
{
|
* button_press/button_release handlers did not handle by themselves.
|
||||||
/* FIXME: This is still very broken. */
|
*/
|
||||||
if (event->type == GDK_BUTTON_PRESS && event->button.button == 3) {
|
|
||||||
gint row, column;
|
|
||||||
|
|
||||||
if (gtk_clist_get_selection_info (GTK_CLIST (file_list),
|
|
||||||
event->button.x, event->button.y,
|
|
||||||
&row, &column)) {
|
|
||||||
gtk_clist_select_row (GTK_CLIST (file_list), row, 0);
|
|
||||||
#if 1
|
|
||||||
gpopup_do_popup2 ((GdkEventButton *) event, panel, NULL);
|
|
||||||
#else
|
|
||||||
gpopup_do_popup ((GdkEventButton *) event, panel,
|
|
||||||
NULL, row, panel->dir.list[row].fname);
|
|
||||||
#endif
|
|
||||||
} else
|
|
||||||
file_list_popup ((GdkEventButton *) event, panel);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
panel_file_list_select_row (GtkWidget *file_list, int row, int column, GdkEvent *event, WPanel *panel)
|
panel_file_list_select_row (GtkWidget *file_list, gint row, gint column,
|
||||||
|
GdkEvent *event, gpointer data)
|
||||||
{
|
{
|
||||||
|
WPanel *panel;
|
||||||
|
|
||||||
|
panel = data;
|
||||||
|
|
||||||
panel->selected = row;
|
panel->selected = row;
|
||||||
do_file_mark (panel, row, 1);
|
do_file_mark (panel, row, 1);
|
||||||
display_mini_info (panel);
|
display_mini_info (panel);
|
||||||
execute_hooks (select_file_hook);
|
execute_hooks (select_file_hook);
|
||||||
|
|
||||||
if (!event)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (event->type) {
|
|
||||||
case GDK_BUTTON_RELEASE:
|
|
||||||
if (event->button.button == 2){
|
|
||||||
char *fullname;
|
|
||||||
|
|
||||||
if (S_ISDIR (panel->dir.list [row].buf.st_mode) ||
|
|
||||||
panel->dir.list [row].f.link_to_dir){
|
|
||||||
fullname = concat_dir_and_file (panel->cwd,
|
|
||||||
panel->dir.list [row].fname);
|
|
||||||
new_panel_at (fullname);
|
|
||||||
g_free (fullname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GDK_2BUTTON_PRESS:
|
|
||||||
if (event->button.button == 1)
|
|
||||||
do_enter (panel);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
panel_file_list_unselect_row (GtkWidget *widget, int row, int columns, GdkEvent *event, WPanel *panel)
|
panel_file_list_unselect_row (GtkWidget *widget, int row, int columns, GdkEvent *event, gpointer data)
|
||||||
{
|
{
|
||||||
|
WPanel *panel;
|
||||||
|
|
||||||
|
panel = data;
|
||||||
do_file_mark (panel, row, 0);
|
do_file_mark (panel, row, 0);
|
||||||
display_mini_info (panel);
|
display_mini_info (panel);
|
||||||
|
|
||||||
if (panel->marked == 0)
|
if (panel->marked == 0)
|
||||||
panel->selected = 0;
|
panel->selected = 0;
|
||||||
}
|
}
|
||||||
@ -630,18 +594,19 @@ panel_setup_drag_scroll (WPanel *panel, int x, int y, desirable_fn desirable, sc
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
panel_configure_file_list (WPanel *panel, GtkWidget *sw, GtkWidget *file_list)
|
panel_file_list_configure (WPanel *panel, GtkWidget *sw, GtkWidget *file_list)
|
||||||
{
|
{
|
||||||
format_e *format = panel->format;
|
format_e *format = panel->format;
|
||||||
GtkObject *adjustment;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Set sorting callback */
|
/* Set sorting callback */
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "click_column",
|
gtk_signal_connect (GTK_OBJECT (file_list), "click_column",
|
||||||
GTK_SIGNAL_FUNC (panel_file_list_column_callback), panel);
|
GTK_SIGNAL_FUNC (panel_file_list_column_callback), panel);
|
||||||
|
|
||||||
/* Configure the CList */
|
/* Avoid clist's broken focusing behavior */
|
||||||
|
GTK_WIDGET_UNSET_FLAGS (file_list, GTK_CAN_FOCUS);
|
||||||
|
|
||||||
|
/* Semi-sane selection mode */
|
||||||
gtk_clist_set_selection_mode (GTK_CLIST (file_list), GTK_SELECTION_EXTENDED);
|
gtk_clist_set_selection_mode (GTK_CLIST (file_list), GTK_SELECTION_EXTENDED);
|
||||||
|
|
||||||
for (i = 0, format = panel->format; format; format = format->next) {
|
for (i = 0, format = panel->format; format; format = format->next) {
|
||||||
@ -655,9 +620,11 @@ panel_configure_file_list (WPanel *panel, GtkWidget *sw, GtkWidget *file_list)
|
|||||||
case J_LEFT:
|
case J_LEFT:
|
||||||
just = GTK_JUSTIFY_LEFT;
|
just = GTK_JUSTIFY_LEFT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case J_RIGHT:
|
case J_RIGHT:
|
||||||
just = GTK_JUSTIFY_RIGHT;
|
just = GTK_JUSTIFY_RIGHT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case J_CENTER:
|
case J_CENTER:
|
||||||
just = GTK_JUSTIFY_CENTER;
|
just = GTK_JUSTIFY_CENTER;
|
||||||
break;
|
break;
|
||||||
@ -666,9 +633,6 @@ panel_configure_file_list (WPanel *panel, GtkWidget *sw, GtkWidget *file_list)
|
|||||||
gtk_clist_set_column_justification (GTK_CLIST (file_list), i, just);
|
gtk_clist_set_column_justification (GTK_CLIST (file_list), i, just);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure the scrolbars */
|
|
||||||
adjustment = GTK_OBJECT (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (sw)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -956,48 +920,35 @@ load_dnd_icons (void)
|
|||||||
drag_multiple_ok = gnome_stock_transparent_window (GNOME_STOCK_PIXMAP_MULTIPLE, NULL);
|
drag_multiple_ok = gnome_stock_transparent_window (GNOME_STOCK_PIXMAP_MULTIPLE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
/* Convenience function to start a drag operation for the icon and file lists */
|
||||||
panel_clist_button_press (GtkWidget *widget, GdkEventButton *event, WPanel *panel)
|
static void
|
||||||
{
|
start_drag (GtkWidget *widget, int button, GdkEvent *event)
|
||||||
if (event->window != GTK_CLIST (widget)->clist_window)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
panel->maybe_start_drag = event->button;
|
|
||||||
|
|
||||||
panel->click_x = event->x;
|
|
||||||
panel->click_y = event->y;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
panel_clist_button_release (GtkWidget *widget, GdkEventButton *event, WPanel *panel)
|
|
||||||
{
|
|
||||||
panel->maybe_start_drag = 0;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
panel_widget_motion (GtkWidget *widget, GdkEventMotion *event, WPanel *panel)
|
|
||||||
{
|
{
|
||||||
GtkTargetList *list;
|
GtkTargetList *list;
|
||||||
GdkDragContext *context;
|
GdkDragContext *context;
|
||||||
|
|
||||||
if (!panel->maybe_start_drag)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if ((abs (event->x - panel->click_x) < 4) ||
|
|
||||||
(abs (event->y - panel->click_y) < 4))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
list = gtk_target_list_new (drag_types, ELEMENTS (drag_types));
|
list = gtk_target_list_new (drag_types, ELEMENTS (drag_types));
|
||||||
|
|
||||||
context = gtk_drag_begin (widget, list,
|
context = gtk_drag_begin (widget, list,
|
||||||
(GDK_ACTION_COPY | GDK_ACTION_MOVE
|
(GDK_ACTION_COPY | GDK_ACTION_MOVE
|
||||||
| GDK_ACTION_LINK | GDK_ACTION_ASK),
|
| GDK_ACTION_LINK | GDK_ACTION_ASK),
|
||||||
panel->maybe_start_drag, (GdkEvent *) event);
|
button, event);
|
||||||
gtk_drag_set_icon_default (context);
|
gtk_drag_set_icon_default (context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
panel_widget_motion (GtkWidget *widget, GdkEventMotion *event, WPanel *panel)
|
||||||
|
{
|
||||||
|
if (!panel->maybe_start_drag)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* This is the same threshold value that is used in gtkdnd.c */
|
||||||
|
|
||||||
|
if (MAX (abs (panel->click_x - event->x),
|
||||||
|
abs (panel->click_y - event->y)) <= 3)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
start_drag (widget, panel->maybe_start_drag, (GdkEvent *) event);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1024,26 +975,6 @@ panel_drag_end (GtkWidget *widget, GdkDragContext *context, WPanel *panel)
|
|||||||
panel->dragging = 0;
|
panel->dragging = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wrapper for the motion_notify callback; it ignores motion events from the
|
|
||||||
* clist if they do not come from the clist_window.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
panel_clist_motion (GtkWidget *widget, GdkEventMotion *event, gpointer data)
|
|
||||||
{
|
|
||||||
if (event->window != GTK_CLIST (widget)->clist_window)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
panel_widget_motion (widget, event, data);
|
|
||||||
|
|
||||||
/* We have to stop the motion event from ever reaching the clist.
|
|
||||||
* Otherwise it will begin dragging/selecting rows when we don't want
|
|
||||||
* that. Yes, the clist widget sucks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "motion_notify_event");
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* panel_clist_scrolling_is_desirable:
|
* panel_clist_scrolling_is_desirable:
|
||||||
*
|
*
|
||||||
@ -1062,7 +993,7 @@ panel_clist_scrolling_is_desirable (WPanel *panel, int x, int y)
|
|||||||
if (va->value > va->lower)
|
if (va->value > va->lower)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
} else {
|
} else {
|
||||||
if (y > (GTK_WIDGET (panel->list)->allocation.height - 10)){
|
if (y > (CLIST_FROM_SW (panel->list)->clist_window_height - 10)) {
|
||||||
if (va->value < va->upper - va->page_size)
|
if (va->value < va->upper - va->page_size)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1103,25 +1034,6 @@ panel_clist_scroll (gpointer data)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convenience function to return whether we are on a valid drop area in a
|
|
||||||
* GtkCList.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
can_drop_on_clist (WPanel *panel, int x, int y)
|
|
||||||
{
|
|
||||||
GtkCList *clist;
|
|
||||||
int border_width;
|
|
||||||
|
|
||||||
clist = CLIST_FROM_SW (panel->list);
|
|
||||||
|
|
||||||
border_width = GTK_CONTAINER (clist)->border_width;
|
|
||||||
|
|
||||||
if (y < border_width + clist->column_title_area.y + clist->column_title_area.height)
|
|
||||||
return FALSE;
|
|
||||||
else
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Callback used for drag motion events over the clist. We set up
|
/* Callback used for drag motion events over the clist. We set up
|
||||||
* auto-scrolling and validate the drop to present the user with the correct
|
* auto-scrolling and validate the drop to present the user with the correct
|
||||||
* feedback.
|
* feedback.
|
||||||
@ -1131,6 +1043,7 @@ panel_clist_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gin
|
|||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
WPanel *panel;
|
WPanel *panel;
|
||||||
|
GtkCList *clist;
|
||||||
GdkDragAction action;
|
GdkDragAction action;
|
||||||
GtkWidget *source_widget;
|
GtkWidget *source_widget;
|
||||||
gint idx;
|
gint idx;
|
||||||
@ -1138,9 +1051,16 @@ panel_clist_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gin
|
|||||||
|
|
||||||
panel = data;
|
panel = data;
|
||||||
|
|
||||||
if (!can_drop_on_clist (panel, x, y)) {
|
/* Normalize the y coordinate to the clist_window */
|
||||||
|
|
||||||
|
clist = CLIST_FROM_SW (panel->list);
|
||||||
|
y -= (GTK_CONTAINER (clist)->border_width
|
||||||
|
+ clist->column_title_area.y
|
||||||
|
+ clist->column_title_area.height);
|
||||||
|
|
||||||
|
if (y < 0) {
|
||||||
gdk_drag_status (context, 0, time);
|
gdk_drag_status (context, 0, time);
|
||||||
return TRUE;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up auto-scrolling */
|
/* Set up auto-scrolling */
|
||||||
@ -1167,6 +1087,9 @@ panel_clist_drag_motion (GtkWidget *widget, GdkDragContext *context, gint x, gin
|
|||||||
fe ? fe->f.marked : FALSE);
|
fe ? fe->f.marked : FALSE);
|
||||||
|
|
||||||
gdk_drag_status (context, action, time);
|
gdk_drag_status (context, action, time);
|
||||||
|
|
||||||
|
out:
|
||||||
|
gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "drag_motion");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1296,6 +1219,43 @@ panel_icon_list_drag_leave (GtkWidget *widget, GdkDragContext *ctx, guint time,
|
|||||||
panel_cancel_drag_scroll (panel);
|
panel_cancel_drag_scroll (panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handler for the row_popup_menu signal of the file list. */
|
||||||
|
static void
|
||||||
|
panel_file_list_row_popup_menu (GtkFList *flist, GdkEventButton *event, gpointer data)
|
||||||
|
{
|
||||||
|
WPanel *panel;
|
||||||
|
|
||||||
|
panel = data;
|
||||||
|
gpopup_do_popup2 (event, panel, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handler for the empty_popup_menu signal of the file list. */
|
||||||
|
static void
|
||||||
|
panel_file_list_empty_popup_menu (GtkFList *flist, GdkEventButton *event, gpointer data)
|
||||||
|
{
|
||||||
|
WPanel *panel;
|
||||||
|
|
||||||
|
panel = data;
|
||||||
|
file_list_popup (event, panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handler for the open_row signal of the file list */
|
||||||
|
static void
|
||||||
|
panel_file_list_open_row (GtkFList *flist, gpointer data)
|
||||||
|
{
|
||||||
|
WPanel *panel;
|
||||||
|
|
||||||
|
panel = data;
|
||||||
|
do_enter (panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handler for the start_drag signal of the file list */
|
||||||
|
static void
|
||||||
|
panel_file_list_start_drag (GtkFList *flist, gint button, GdkEvent *event, gpointer data)
|
||||||
|
{
|
||||||
|
start_drag (GTK_WIDGET (flist), button, event);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create, setup the file listing display.
|
* Create, setup the file listing display.
|
||||||
*/
|
*/
|
||||||
@ -1318,30 +1278,38 @@ panel_create_file_list (WPanel *panel)
|
|||||||
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
|
||||||
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||||||
|
|
||||||
file_list = gtk_clist_new_with_titles (items, titles);
|
file_list = gtk_flist_new_with_titles (panel, items, titles);
|
||||||
gtk_container_add (GTK_CONTAINER (sw), file_list);
|
gtk_container_add (GTK_CONTAINER (sw), file_list);
|
||||||
gtk_widget_show (file_list);
|
gtk_widget_show (file_list);
|
||||||
|
|
||||||
panel_configure_file_list (panel, sw, file_list);
|
panel_file_list_configure (panel, sw, file_list);
|
||||||
g_free (titles);
|
g_free (titles);
|
||||||
|
|
||||||
gtk_signal_connect_after (GTK_OBJECT (sw), "size_allocate",
|
gtk_signal_connect_after (GTK_OBJECT (sw), "size_allocate",
|
||||||
GTK_SIGNAL_FUNC (panel_file_list_size_allocate_hook),
|
(GtkSignalFunc) panel_file_list_size_allocate_hook,
|
||||||
panel);
|
panel);
|
||||||
|
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "select_row",
|
gtk_signal_connect (GTK_OBJECT (file_list), "select_row",
|
||||||
GTK_SIGNAL_FUNC (panel_file_list_select_row),
|
(GtkSignalFunc) panel_file_list_select_row,
|
||||||
panel);
|
panel);
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "unselect_row",
|
gtk_signal_connect (GTK_OBJECT (file_list), "unselect_row",
|
||||||
GTK_SIGNAL_FUNC (panel_file_list_unselect_row),
|
(GtkSignalFunc) panel_file_list_unselect_row,
|
||||||
panel);
|
panel);
|
||||||
#if 1
|
|
||||||
gtk_signal_connect_after (GTK_OBJECT (file_list), "button_press_event",
|
/* Connect to the flist signals */
|
||||||
GTK_SIGNAL_FUNC (panel_file_list_press_row),
|
|
||||||
|
gtk_signal_connect (GTK_OBJECT (file_list), "row_popup_menu",
|
||||||
|
(GtkSignalFunc) panel_file_list_row_popup_menu,
|
||||||
|
panel);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (file_list), "empty_popup_menu",
|
||||||
|
(GtkSignalFunc) panel_file_list_empty_popup_menu,
|
||||||
|
panel);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (file_list), "open_row",
|
||||||
|
(GtkSignalFunc) panel_file_list_open_row,
|
||||||
|
panel);
|
||||||
|
gtk_signal_connect (GTK_OBJECT (file_list), "start_drag",
|
||||||
|
(GtkSignalFunc) panel_file_list_start_drag,
|
||||||
panel);
|
panel);
|
||||||
#endif
|
|
||||||
gtk_clist_set_button_actions (GTK_CLIST (file_list), 1, GTK_BUTTON_SELECTS | GTK_BUTTON_DRAGS);
|
|
||||||
gtk_clist_set_button_actions (GTK_CLIST (file_list), 2, GTK_BUTTON_SELECTS);
|
|
||||||
|
|
||||||
/* Set up drag and drop */
|
/* Set up drag and drop */
|
||||||
|
|
||||||
@ -1351,12 +1319,7 @@ panel_create_file_list (WPanel *panel)
|
|||||||
GTK_DEST_DEFAULT_DROP,
|
GTK_DEST_DEFAULT_DROP,
|
||||||
drop_types, ELEMENTS (drop_types),
|
drop_types, ELEMENTS (drop_types),
|
||||||
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);
|
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);
|
||||||
#if 0
|
|
||||||
/* Make directories draggable */
|
|
||||||
gtk_drag_source_set (GTK_WIDGET (file_list), GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
|
|
||||||
drag_types, ELEMENTS (drag_types),
|
|
||||||
GDK_ACTION_LINK | GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_ASK);
|
|
||||||
#endif
|
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "drag_data_get",
|
gtk_signal_connect (GTK_OBJECT (file_list), "drag_data_get",
|
||||||
GTK_SIGNAL_FUNC (panel_drag_data_get), panel);
|
GTK_SIGNAL_FUNC (panel_drag_data_get), panel);
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "drag_data_delete",
|
gtk_signal_connect (GTK_OBJECT (file_list), "drag_data_delete",
|
||||||
@ -1372,20 +1335,6 @@ panel_create_file_list (WPanel *panel)
|
|||||||
GTK_SIGNAL_FUNC (panel_clist_drag_motion), panel);
|
GTK_SIGNAL_FUNC (panel_clist_drag_motion), panel);
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "drag_leave",
|
gtk_signal_connect (GTK_OBJECT (file_list), "drag_leave",
|
||||||
GTK_SIGNAL_FUNC (panel_clist_drag_leave), panel);
|
GTK_SIGNAL_FUNC (panel_clist_drag_leave), panel);
|
||||||
|
|
||||||
/* These implement our drag-start activation code. We need to
|
|
||||||
* manually activate the drag as the DnD code in Gtk+ will
|
|
||||||
* make the scrollbars in the CList activate drags when they
|
|
||||||
* are moved.
|
|
||||||
*/
|
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "button_press_event",
|
|
||||||
GTK_SIGNAL_FUNC (panel_clist_button_press), panel);
|
|
||||||
|
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "button_release_event",
|
|
||||||
GTK_SIGNAL_FUNC (panel_clist_button_release), panel);
|
|
||||||
|
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "motion_notify_event",
|
|
||||||
GTK_SIGNAL_FUNC (panel_clist_motion), panel);
|
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "drag_begin",
|
gtk_signal_connect (GTK_OBJECT (file_list), "drag_begin",
|
||||||
GTK_SIGNAL_FUNC (panel_drag_begin), panel);
|
GTK_SIGNAL_FUNC (panel_drag_begin), panel);
|
||||||
gtk_signal_connect (GTK_OBJECT (file_list), "drag_end",
|
gtk_signal_connect (GTK_OBJECT (file_list), "drag_end",
|
||||||
@ -1410,14 +1359,9 @@ panel_icon_list_select_icon (GtkWidget *widget, int index, GdkEvent *event, WPan
|
|||||||
|
|
||||||
switch (event->type){
|
switch (event->type){
|
||||||
case GDK_BUTTON_PRESS:
|
case GDK_BUTTON_PRESS:
|
||||||
if (event->button.button == 3) {
|
if (event->button.button == 3)
|
||||||
#if 1
|
|
||||||
gpopup_do_popup2 ((GdkEventButton *) event, panel, NULL);
|
gpopup_do_popup2 ((GdkEventButton *) event, panel, NULL);
|
||||||
#else
|
|
||||||
gpopup_do_popup ((GdkEventButton *) event, panel,
|
|
||||||
NULL, index, panel->dir.list[index].fname);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GDK_BUTTON_RELEASE:
|
case GDK_BUTTON_RELEASE:
|
||||||
|
@ -148,6 +148,7 @@ typedef struct {
|
|||||||
void *back_b;
|
void *back_b;
|
||||||
void *fwd_b;
|
void *fwd_b;
|
||||||
void *up_b;
|
void *up_b;
|
||||||
|
|
||||||
/* Used during drag and drop */
|
/* Used during drag and drop */
|
||||||
int maybe_start_drag;
|
int maybe_start_drag;
|
||||||
int click_x, click_y;
|
int click_x, click_y;
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user