SF.net SVN: geany:[3436] trunk

ntrel at users.sourceforge.net ntrel at xxxxx
Fri Jan 2 13:37:42 UTC 2009


Revision: 3436
          http://geany.svn.sourceforge.net/geany/?rev=3436&view=rev
Author:   ntrel
Date:     2009-01-02 13:37:40 +0000 (Fri, 02 Jan 2009)

Log Message:
-----------
Add dialog for switching to last used tab, which disappears when
releasing the modifier key. (Useful once MRU switching is
implemented).
Connect window key-press-event in keybindings.c.

Modified Paths:
--------------
    trunk/ChangeLog
    trunk/src/keybindings.c
    trunk/src/keybindings.h
    trunk/src/main.c

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2009-01-01 12:59:04 UTC (rev 3435)
+++ trunk/ChangeLog	2009-01-02 13:37:40 UTC (rev 3436)
@@ -1,3 +1,12 @@
+2009-01-02  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
+
+ * src/keybindings.c, src/keybindings.h, src/main.c:
+   Add dialog for switching to last used tab, which disappears when
+   releasing the modifier key. (Useful once MRU switching is
+   implemented).
+   Connect window key-press-event in keybindings.c.
+
+
 2008-12-30  Nick Treleaven  <nick(dot)treleaven(at)btinternet(dot)com>
 
  * doc/geany.txt, doc/geany.html:

Modified: trunk/src/keybindings.c
===================================================================
--- trunk/src/keybindings.c	2009-01-01 12:59:04 UTC (rev 3435)
+++ trunk/src/keybindings.c	2009-01-02 13:37:40 UTC (rev 3436)
@@ -45,6 +45,7 @@
 #include "symbols.h"
 #include "vte.h"
 #include "toolbar.h"
+#include "geanywraplabel.h"
 
 
 GPtrArray *keybinding_groups;	/* array of GeanyKeyGroup pointers */
@@ -57,7 +58,15 @@
 static GtkAccelGroup *kb_accel_group = NULL;
 static const gboolean swap_alt_tab_order = FALSE;
 
+static gboolean switch_dialog_cancelled = TRUE;
+static GtkWidget *switch_dialog = NULL;
+static GtkWidget *switch_dialog_label = NULL;
 
+
+/* central keypress event handler, almost all keypress events go to this function */
+static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data);
+static gboolean on_key_release_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data);
+
 static gboolean check_current_word(void);
 static gboolean read_current_word(void);
 
@@ -486,6 +495,10 @@
 	init_default_kb();
 
 	gtk_window_add_accel_group(GTK_WINDOW(main_widgets.window), kb_accel_group);
+
+	g_signal_connect(main_widgets.window, "key-press-event", G_CALLBACK(on_key_press_event), NULL);
+	/* in case the switch dialog misses an event while drawing the dialog */
+	g_signal_connect(main_widgets.window, "key-release-event", G_CALLBACK(on_key_release_event), NULL);
 }
 
 
@@ -926,7 +939,7 @@
 
 
 /* central keypress event handler, almost all keypress events go to this function */
-gboolean keybindings_got_event(GtkWidget *widget, GdkEventKey *ev, gpointer user_data)
+static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *ev, gpointer user_data)
 {
 	guint state, keyval;
 	gsize g, i;
@@ -981,6 +994,29 @@
 }
 
 
+static gboolean is_modifier_key(guint keyval)
+{
+	switch (keyval)
+	{
+		case GDK_Shift_L:
+		case GDK_Shift_R:
+		case GDK_Control_L:
+		case GDK_Control_R:
+		case GDK_Meta_L:
+		case GDK_Meta_R:
+		case GDK_Alt_L:
+		case GDK_Alt_R:
+		case GDK_Super_L:
+		case GDK_Super_R:
+		case GDK_Hyper_L:
+		case GDK_Hyper_R:
+			return TRUE;
+		default:
+			return FALSE;
+	}
+}
+
+
 GeanyKeyBinding *keybindings_lookup_item(guint group_id, guint key_id)
 {
 	GeanyKeyGroup *group;
@@ -1303,15 +1339,110 @@
 	switch_document(RIGHT);
 }
 
+
+static gboolean on_key_release_event(GtkWidget *widget, GdkEventKey *ev, gpointer user_data)
+{
+	/* user may have rebound keybinding to a different modifier than Ctrl, so check all */
+	if (!switch_dialog_cancelled && is_modifier_key(ev->keyval))
+	{
+		switch_dialog_cancelled = TRUE;
+
+		if (switch_dialog && GTK_WIDGET_VISIBLE(switch_dialog))
+			gtk_widget_hide(switch_dialog);
+	}
+	return FALSE;
+}
+
+
+static GtkWidget *ui_minimal_dialog_new(GtkWindow *parent, const gchar *title)
+{
+	GtkWidget *dialog;
+
+	dialog = gtk_window_new(GTK_WINDOW_POPUP);
+
+	if (parent)
+	{
+		gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
+		gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
+	}
+	gtk_window_set_title(GTK_WINDOW(dialog), title);
+	gtk_window_set_type_hint(GTK_WINDOW(dialog), GDK_WINDOW_TYPE_HINT_DIALOG);
+	gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_CENTER_ON_PARENT);
+
+	gtk_widget_set_name(dialog, "GeanyDialog");
+	return dialog;
+}
+
+
+static GtkWidget *create_switch_dialog(void)
+{
+	GtkWidget *dialog, *widget, *vbox;
+
+	dialog = ui_minimal_dialog_new(GTK_WINDOW(main_widgets.window), _("Switch to Document"));
+	gtk_window_set_decorated(GTK_WINDOW(dialog), FALSE);
+	gtk_window_set_default_size(GTK_WINDOW(dialog), 150, -1);
+
+	vbox = gtk_vbox_new(FALSE, 6);
+	gtk_container_set_border_width(GTK_CONTAINER(vbox), 12);
+	gtk_container_add(GTK_CONTAINER(dialog), vbox);
+
+	widget = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_BUTTON);
+	gtk_container_add(GTK_CONTAINER(vbox), widget);
+
+	widget = geany_wrap_label_new(NULL);
+	gtk_label_set_justify(GTK_LABEL(widget), GTK_JUSTIFY_CENTER);
+	gtk_container_add(GTK_CONTAINER(vbox), widget);
+	switch_dialog_label = widget;
+
+	g_signal_connect(dialog, "key-release-event", G_CALLBACK(on_key_release_event), NULL);
+	return dialog;
+}
+
+
+static gboolean on_switch_timeout(G_GNUC_UNUSED gpointer data)
+{
+	if (switch_dialog_cancelled)
+		return FALSE;
+
+	if (!switch_dialog)
+		switch_dialog = create_switch_dialog();
+
+	geany_wrap_label_set_text(GTK_LABEL(switch_dialog_label),
+		DOC_FILENAME(document_get_current()));
+	gtk_widget_show_all(switch_dialog);
+	return FALSE;
+}
+
+
 static void cb_func_switch_tablastused(G_GNUC_UNUSED guint key_id)
 {
+	/* TODO: MRU switching order */
 	GeanyDocument *last_doc = callbacks_data.last_doc;
 
-	if (DOC_VALID(last_doc))
-		gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
-			document_get_notebook_page(last_doc));
+	if (!DOC_VALID(last_doc))
+		return;
+
+	gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
+		document_get_notebook_page(last_doc));
+
+	/* if there's a modifier key, we can switch back in MRU order each time unless
+	 * the key is released */
+	if (!switch_dialog_cancelled)
+	{
+		on_switch_timeout(NULL);	/* update filename label */
+	}
+	else
+	if (keybindings_lookup_item(GEANY_KEY_GROUP_NOTEBOOK,
+		GEANY_KEYS_NOTEBOOK_SWITCHTABLASTUSED)->mods)
+	{
+		switch_dialog_cancelled = FALSE;
+
+		/* delay showing dialog to give user time to let go of any modifier keys */
+		g_timeout_add(600, on_switch_timeout, NULL);
+	}
 }
 
+
 /* move document left/right/first/last */
 static void cb_func_move_tab(guint key_id)
 {

Modified: trunk/src/keybindings.h
===================================================================
--- trunk/src/keybindings.h	2009-01-01 12:59:04 UTC (rev 3435)
+++ trunk/src/keybindings.h	2009-01-02 13:37:40 UTC (rev 3436)
@@ -334,8 +334,5 @@
 
 void keybindings_show_shortcuts(void);
 
-/* central keypress event handler, almost all keypress events go to this function */
-gboolean keybindings_got_event(GtkWidget *widget, GdkEventKey *event, gpointer user_data);
-
 #endif
 

Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c	2009-01-01 12:59:04 UTC (rev 3435)
+++ trunk/src/main.c	2009-01-02 13:37:40 UTC (rev 3436)
@@ -962,7 +962,6 @@
 		GtkWidget *entry;
 
 		g_signal_connect(main_widgets.window, "delete-event", G_CALLBACK(on_exit_clicked), NULL);
-		g_signal_connect(main_widgets.window, "key-press-event", G_CALLBACK(keybindings_got_event), NULL);
 		g_signal_connect(main_widgets.toolbar, "button-press-event", G_CALLBACK(toolbar_popup_menu), NULL);
 
 		g_signal_connect(ui_lookup_widget(main_widgets.window, "textview_scribble"),


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the Commits mailing list