From 0e6e5c9a87749a5f786bd8a23247692e181ce824 Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Tue, 11 Jan 2000 13:34:32 +0000 Subject: [PATCH] r163: Choosing something from the selection menu when nothing is selected is no longer an error - it goes into target mode. This is very nice with single-click navigation! --- ROX-Filer/src/collection.c | 41 ++++++++++++++++- ROX-Filer/src/collection.h | 9 ++++ ROX-Filer/src/filer.c | 7 ++- ROX-Filer/src/menu.c | 109 +++++++++++++++++++++++++++++++++------------ 4 files changed, 134 insertions(+), 32 deletions(-) diff --git a/ROX-Filer/src/collection.c b/ROX-Filer/src/collection.c index c4f99b57..9ca89b40 100644 --- a/ROX-Filer/src/collection.c +++ b/ROX-Filer/src/collection.c @@ -80,6 +80,8 @@ static guint32 current_event_time = GDK_CURRENT_TIME; static GtkWidgetClass *parent_class = NULL; +static GdkCursor *crosshair = NULL; + /* Static prototypes */ static void draw_one_item(Collection *collection, int item, @@ -261,6 +263,9 @@ static void collection_class_init(CollectionClass *class) static void collection_init(Collection *object) { + if (!crosshair) + crosshair = gdk_cursor_new(GDK_CROSSHAIR); + object->panel = FALSE; object->number_of_items = 0; object->number_selected = 0; @@ -902,7 +907,7 @@ static gint collection_button_press(GtkWidget *widget, else return FALSE; /* Ignore extra presses */ } - + if (event->state & GDK_CONTROL_MASK && !collection_single_click) action = 2; else @@ -934,6 +939,22 @@ static gint collection_button_press(GtkWidget *widget, } } + if (collection->target_cb) + { + CollectionTargetFunc cb = collection->target_cb; + gpointer data = collection->target_data; + + collection_target(collection, NULL, NULL); + if (collection->buttons_pressed) + { + gtk_grab_remove(widget); + collection->buttons_pressed = 0; + } + if (item > -1) + cb(collection, item, data); + return TRUE; + } + collection->drag_box_x[0] = event->x; collection->drag_box_y[0] = event->y; collection->item_clicked = item; @@ -1815,3 +1836,21 @@ void collection_delete_if(Collection *collection, } } } + +/* Display a cross-hair pointer and the next time an item is clicked, + * call the callback function. If the background is clicked or NULL + * is passed as the callback then revert to normal operation. + */ +void collection_target(Collection *collection, + CollectionTargetFunc callback, + gpointer user_data) +{ + g_return_if_fail(collection != NULL); + g_return_if_fail(IS_COLLECTION(collection)); + + collection->target_cb = callback; + collection->target_data = user_data; + + gdk_window_set_cursor(GTK_WIDGET(collection)->window, + callback ? crosshair : NULL); +} diff --git a/ROX-Filer/src/collection.h b/ROX-Filer/src/collection.h index 253658e9..0b13ec3d 100644 --- a/ROX-Filer/src/collection.h +++ b/ROX-Filer/src/collection.h @@ -46,6 +46,9 @@ typedef gboolean (*CollectionTestFunc)( Collection *collection, int point_x, int point_y, CollectionItem *item, int width, int height); +typedef void (*CollectionTargetFunc)(Collection *collection, + gint item, + gpointer user_data); struct _CollectionItem { @@ -84,6 +87,9 @@ struct _Collection int item_clicked; /* For collection_single_click */ guint array_size; + + CollectionTargetFunc target_cb; + gpointer target_data; }; struct _CollectionClass @@ -138,6 +144,9 @@ void collection_delete_if (Collection *collection, gboolean (*test)(gpointer item, gpointer data), gpointer data); +void collection_target (Collection *collection, + CollectionTargetFunc callback, + gpointer user_data); #ifdef __cplusplus } diff --git a/ROX-Filer/src/filer.c b/ROX-Filer/src/filer.c index 2da516a1..f8f29e11 100644 --- a/ROX-Filer/src/filer.c +++ b/ROX-Filer/src/filer.c @@ -160,6 +160,8 @@ enum TARGET_URI_LIST, }; +static GdkCursor *busy_cursor = NULL; + void filer_init() { xa_string = gdk_atom_intern("STRING", FALSE); @@ -170,6 +172,8 @@ void filer_init() option_register("filer_toolbar", filer_toolbar); fixed_font = gdk_font_load("fixed"); + + busy_cursor = gdk_cursor_new(GDK_WATCH); } static gboolean if_deleted(gpointer item, gpointer removed) @@ -252,8 +256,7 @@ static void update_display(Directory *dir, static void attach(FilerWindow *filer_window) { - gdk_window_set_cursor(filer_window->window->window, - gdk_cursor_new(GDK_WATCH)); + gdk_window_set_cursor(filer_window->window->window, busy_cursor); collection_clear(filer_window->collection); dir_attach(filer_window->directory, (DirCallback) update_display, filer_window); diff --git a/ROX-Filer/src/menu.c b/ROX-Filer/src/menu.c index 134cc6c5..8d393d48 100644 --- a/ROX-Filer/src/menu.c +++ b/ROX-Filer/src/menu.c @@ -61,11 +61,13 @@ static GtkWidget *xterm_here_entry; static char *xterm_here_value; /* Static prototypes */ + static void position_menu(GtkMenu *menu, gint *x, gint *y, gpointer data); static void menu_closed(GtkWidget *widget); static void items_sensitive(GtkWidget *menu, int from, int n, gboolean state); static char *load_xterm_here(char *data); +/* Note that for these callbacks none of the arguments are used. */ static void not_yet(gpointer data, guint action, GtkWidget *widget); static void large(gpointer data, guint action, GtkWidget *widget); @@ -417,15 +419,11 @@ void show_filer_menu(FilerWindow *filer_window, GdkEventButton *event, switch (filer_window->collection->number_selected) { case 0: - g_string_assign(buffer, ""); - items_sensitive(file_menu, 0, 6, FALSE); - items_sensitive(file_menu, 7, -1, FALSE); - gtk_widget_set_sensitive(file_label, FALSE); + g_string_assign(buffer, "Next click"); + items_sensitive(file_menu, 0, 6, TRUE); break; case 1: items_sensitive(file_menu, 0, 6, TRUE); - items_sensitive(file_menu, 7, -1, TRUE); - gtk_widget_set_sensitive(file_label, TRUE); file_item = selected_item(filer_window->collection); g_string_sprintf(buffer, "%s '%s'", basetype_name(file_item), @@ -433,8 +431,6 @@ void show_filer_menu(FilerWindow *filer_window, GdkEventButton *event, break; default: items_sensitive(file_menu, 0, 6, FALSE); - items_sensitive(file_menu, 7, -1, TRUE); - gtk_widget_set_sensitive(file_label, TRUE); g_string_sprintf(buffer, "%d items", filer_window->collection->number_selected); break; @@ -467,6 +463,19 @@ static void menu_closed(GtkWidget *widget) } } +void target_callback(Collection *collection, gint item, gpointer real_fn) +{ + g_return_if_fail(window_with_focus != NULL); + g_return_if_fail(window_with_focus->collection == collection); + g_return_if_fail(real_fn != NULL); + + collection_wink_item(collection, item); + collection_clear_selection(collection); + collection_select_item(collection, item); + ((CollectionTargetFunc)real_fn)(NULL, 0, collection); + collection_unselect_item(collection, item); +} + /* Actions */ /* Fake action to warn when a menu item does nothing */ @@ -549,21 +558,33 @@ static void mount(gpointer data, guint action, GtkWidget *widget) { g_return_if_fail(window_with_focus != NULL); - action_mount(window_with_focus, NULL); + if (window_with_focus->collection->number_selected == 0) + collection_target(window_with_focus->collection, + target_callback, mount); + else + action_mount(window_with_focus, NULL); } static void delete(gpointer data, guint action, GtkWidget *widget) { g_return_if_fail(window_with_focus != NULL); - action_delete(window_with_focus); + if (window_with_focus->collection->number_selected == 0) + collection_target(window_with_focus->collection, + target_callback, delete); + else + action_delete(window_with_focus); } static void usage(gpointer data, guint action, GtkWidget *widget) { g_return_if_fail(window_with_focus != NULL); - action_usage(window_with_focus); + if (window_with_focus->collection->number_selected == 0) + collection_target(window_with_focus->collection, + target_callback, usage); + else + action_usage(window_with_focus); } static gboolean copy_cb(char *initial, char *path) @@ -615,9 +636,14 @@ static void copy_item(gpointer data, guint action, GtkWidget *widget) g_return_if_fail(window_with_focus != NULL); collection = window_with_focus->collection; - if (collection->number_selected != 1) - report_error("ROX-Filer", "You must select a single " - "item to copy"); + if (collection->number_selected > 1) + { + report_error("ROX-Filer", "You cannot do this to more than " + "one item at a time"); + return; + } + else if (collection->number_selected != 1) + collection_target(collection, target_callback, copy_item); else { DirItem *item = selected_item(collection); @@ -646,9 +672,14 @@ static void rename_item(gpointer data, guint action, GtkWidget *widget) g_return_if_fail(window_with_focus != NULL); collection = window_with_focus->collection; - if (collection->number_selected != 1) - report_error("ROX-Filer", "You must select a single " - "item to rename"); + if (collection->number_selected > 1) + { + report_error("ROX-Filer", "You cannot do this to more than " + "one item at a time"); + return; + } + else if (collection->number_selected != 1) + collection_target(collection, target_callback, rename_item); else { DirItem *item = selected_item(collection); @@ -677,9 +708,14 @@ static void link_item(gpointer data, guint action, GtkWidget *widget) g_return_if_fail(window_with_focus != NULL); collection = window_with_focus->collection; - if (collection->number_selected != 1) - report_error("ROX-Filer", "You must select a single " - "item to link"); + if (collection->number_selected > 1) + { + report_error("ROX-Filer", "You cannot do this to more than " + "one item at a time"); + return; + } + else if (collection->number_selected != 1) + collection_target(collection, target_callback, link_item); else { DirItem *item = selected_item(collection); @@ -698,9 +734,14 @@ static void open_file(gpointer data, guint action, GtkWidget *widget) g_return_if_fail(window_with_focus != NULL); collection = window_with_focus->collection; - if (collection->number_selected != 1) - report_error("ROX-Filer", "You must select a single " - "file or application to open"); + if (collection->number_selected > 1) + { + report_error("ROX-Filer", "You cannot do this to more than " + "one item at a time"); + return; + } + else if (collection->number_selected != 1) + collection_target(collection, target_callback, open_file); else filer_openitem(window_with_focus, selected_item(collection), TRUE, FALSE); @@ -724,10 +765,15 @@ static void show_file_info(gpointer data, guint action, GtkWidget *widget) g_return_if_fail(window_with_focus != NULL); collection = window_with_focus->collection; - if (collection->number_selected != 1) + if (collection->number_selected > 1) + { + report_error("ROX-Filer", "You cannot do this to more than " + "one item at a time"); + return; + } + else if (collection->number_selected != 1) { - report_error("ROX-Filer", "You must select a single " - "item before using Info"); + collection_target(collection, target_callback, show_file_info); return; } file = selected_item(collection); @@ -913,10 +959,15 @@ static void help(gpointer data, guint action, GtkWidget *widget) g_return_if_fail(window_with_focus != NULL); collection = window_with_focus->collection; - if (collection->number_selected != 1) + if (collection->number_selected > 1) + { + report_error("ROX-Filer", "You cannot do this to more than " + "one item at a time"); + return; + } + else if (collection->number_selected != 1) { - report_error("ROX-Filer", "You must select a single " - "item to get help on"); + collection_target(collection, target_callback, help); return; } item = selected_item(collection); -- 2.11.4.GIT