CList "keyfocus" patch



 
Index: gtkclist.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkclist.c,v
retrieving revision 1.167
diff -u -b -B -r1.167 gtkclist.c
--- gtkclist.c	2000/05/12 15:25:38	1.167
+++ gtkclist.c	2000/05/28 20:39:36
@@ -27,6 +27,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <gdk/gdki18n.h> 
 #include "config.h"
 #include "gtkmain.h"
 #include "gtkclist.h"
@@ -55,6 +56,10 @@
 /* used for auto-scrolling */
 #define SCROLL_TIME  100
 
+/* used for keypress string concat */
+#define KEYFOCUS_TIMEOUT 180
+
+
 /* gives the top pixel of the given row in context of
  * the clist's voffset */
 #define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \
@@ -453,6 +458,15 @@
 				       gint              y,
 				       GtkCListDestInfo *dest_info);
 
+/* Private for now */
+static
+gint
+gtk_clist_find_row_from_text (GtkCList *clist,
+			      const gchar *match, gint start_row, gint column);
+static 
+void
+gtk_clist_moveto_with_focus(GtkCList *clist, gint row, gint column);
+
 
 
 static GtkContainerClass *parent_class = NULL;
@@ -991,6 +1005,9 @@
   clist->compare = default_compare;
   clist->sort_type = GTK_SORT_ASCENDING;
   clist->sort_column = 0;
+
+  clist->keyfocus_string = NULL;
+  clist->keyfocus_lasttime = 0;
 }
 
 /* Constructors */
@@ -2958,6 +2975,38 @@
     move_vertical (clist, row, row_align);
 }
 
+/*
+ * Like gtk_clist_moveto - But sets target as new row with focus
+ * (?) Anybody using gtk_clist_moveto() from outside this widget?
+ */
+static void 
+gtk_clist_moveto_with_focus(GtkCList *clist, gint row, gint column)
+{
+
+  g_return_if_fail (clist != NULL);
+  g_return_if_fail (GTK_IS_CLIST (clist));
+  
+  if (row < -1 || row >= clist->rows)
+    return;
+  if (column < -1 || column >= clist->columns)
+    return;
+
+  gtk_clist_freeze(clist);
+	
+  clist->focus_row = row;
+
+  if (ROW_TOP_YPIXEL(clist, row) < 0)
+    gtk_clist_moveto(clist, row, column, 0, 0);
+  else if (ROW_TOP_YPIXEL(clist, row) + clist->row_height >clist->clist_window_height)
+    gtk_clist_moveto(clist, row, column, 1, 0);
+
+  gtk_clist_thaw(clist);
+
+}
+
+
+
+
 void
 gtk_clist_set_row_height (GtkCList *clist,
 			  guint     height)
@@ -4864,6 +4913,43 @@
     }
 }
 
+/*
+ * TODO: rc enable/disable via setting of keyfocus_timeout
+ */
+static void
+handle_keyfocus (GtkCList *clist, GdkEventKey *event)
+{
+
+  char *str;
+  int row;
+  	
+  if (clist->keyfocus_string != NULL) 
+    if ( event->time > clist->keyfocus_lasttime + KEYFOCUS_TIMEOUT) 
+      {
+        g_free(clist->keyfocus_string);
+        clist->keyfocus_string = NULL;
+      }	 
+
+  if (clist->keyfocus_string == NULL) 
+    clist->keyfocus_string = g_strdup(event->string);
+  else 
+    {	
+      str = g_strconcat(clist->keyfocus_string, event->string, NULL);
+      g_free(clist->keyfocus_string);
+      clist->keyfocus_string = str;
+    }
+
+  row = gtk_clist_find_row_from_text(clist, 
+          clist->keyfocus_string, clist->focus_row+1, 0); /* FIXME: column number arg*/
+
+  if (row != -1) 
+    gtk_clist_moveto_with_focus(clist, row, -1);	
+
+  clist->keyfocus_lasttime = event->time;
+
+}
+
+
 static gint
 gtk_clist_key_press (GtkWidget   *widget,
 		     GdkEventKey *event)
@@ -4887,6 +4973,12 @@
 	return gtk_container_focus (GTK_CONTAINER (widget),
 				    GTK_DIR_TAB_FORWARD);
     default:
+      if (!(event->state & (GDK_MODIFIER_MASK ^ GDK_SHIFT_MASK)) 
+          && gdk_iswalnum(event->keyval)) 
+        {
+          handle_keyfocus(GTK_CLIST (widget), event);
+          return TRUE;
+        }
       break;
     }
   return FALSE;
@@ -7894,4 +7986,68 @@
       
       clist->button_actions[button] = button_actions;
     }
+}
+
+
+/*
+ * TODO: 
+ * - make public (?)
+ * - regex version? no.
+ * - binary search on sorted list
+ * - if (column == -1) 
+ *     column = clist->sort_column, or 1st non GTK_CELL_PIXMAP column
+ */
+static
+gint
+gtk_clist_find_row_from_text (GtkCList *clist,
+			      const gchar *match, gint start_row, gint column)
+{
+  GList *list;
+  GtkCListRow *clist_row;
+  gint n;
+  gchar *text;
+  gint mlen;
+    
+  g_return_val_if_fail (clist != NULL, -1);
+  g_return_val_if_fail (GTK_IS_CLIST (clist), -1);
+
+
+  if (start_row < 0 || start_row >= clist->rows)
+    return -1;
+  if (column < 0 || column >= clist->columns)
+    return -1;
+  
+  mlen = strlen(match);
+  
+  for (n = start_row, list = g_list_nth(clist->row_list, n); list; n++, list = list->next) {
+
+    clist_row = ROW_ELEMENT (clist, n)->data;
+
+    switch (clist_row->cell[column].type)
+      {
+      case GTK_CELL_TEXT:
+        text = GTK_CELL_TEXT (clist_row->cell[column])->text;
+        if (!g_strncasecmp(text, match, mlen))
+          {
+            {
+	      return n;
+            }
+          }
+      	break;
+      case GTK_CELL_PIXTEXT:
+        text = GTK_CELL_PIXTEXT (clist_row->cell[column])->text;        
+        if (!g_strncasecmp(text, match, mlen))
+          {
+            {
+	      return n;
+	    }
+	  }
+      	break;
+      default:
+        break;
+      }
+  }
+    
+  return -1;
+
 }
Index: gtkclist.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkclist.h,v
retrieving revision 1.50
diff -u -b -B -r1.50 gtkclist.h
--- gtkclist.h	2000/02/29 13:15:10	1.50
+++ gtkclist.h	2000/05/28 20:39:36
@@ -237,6 +237,10 @@
   GtkSortType sort_type;
   GtkCListCompareFunc compare;
   gint sort_column;
+
+  /* keyboard focus navigation */
+  gchar *keyfocus_string;
+  gint keyfocus_lasttime;
 };
 
 struct _GtkCListClass


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]