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

Re: gEDA-dev: [PATCH] gschem: Visual feedback for keyboard commands



On Mon, Jun 04, 2007 at 08:48:34AM -0400, Ales Hvezda wrote:
> >I can't reproduce this. How did you get the same string in two
> >different windows?
> >
> 
> 	Ah yes, some more detail would be more helpful.  Here's how you
> produce (with your first patch):
> 
> 1) Open up two gschem windows
> 2) Hit Return a few times in one
> 3) Go over to the other one press "3" or some other unbound key
> 4) Notice that the second window has the original Returns plus the 3's.
> 5) If you go back to the first window, and press another unbound key (4),
>    you will see the original Returns, the 3's and additional Returns, and 
>    now the 4.

Thanks, I fixed this by making keyaccel_string a per-toplevel variable.
Please test the attached patch.

-- 
Ivan Stankovic, ivan.stankovic@fer.hr

"Protect your digital freedom and privacy, eliminate DRM, 
learn more at http://www.defectivebydesign.org/what_is_drm"

---
 gschem/src/g_keys.c      |   69 ++++++++++++++++++++++++++++++++++++++++-----
 gschem/src/i_basic.c     |    8 +++++
 libgeda/include/struct.h |    3 ++
 libgeda/src/s_toplevel.c |    2 +
 4 files changed, 74 insertions(+), 8 deletions(-)

diff --git a/gschem/src/g_keys.c b/gschem/src/g_keys.c
index cb78e08..683f824 100644
--- a/gschem/src/g_keys.c
+++ b/gschem/src/g_keys.c
@@ -48,6 +48,7 @@
 /* for now this only supports single chars, not shift/alt/ctrl etc... */
 int g_keys_execute(int state, int keyval)
 {
+  TOPLEVEL *w = global_window_current;
   char *guile_string = NULL;
   char *modifier = NULL;
   char *key_name = NULL;
@@ -70,16 +71,37 @@ int g_keys_execute(int state, int keyval)
   }
 
   if (state & GDK_SHIFT_MASK) {
-    modifier = g_strdup_printf("\"Shift ");
+    modifier = g_strdup_printf("Shift ");
   } else if (state & GDK_CONTROL_MASK) {
-    modifier = g_strdup_printf("\"Control ");
+    modifier = g_strdup_printf("Control ");
   } else if (state & GDK_MOD1_MASK) {
-    modifier = g_strdup_printf("\"Alt ");
+    modifier = g_strdup_printf("Alt ");
+  } else
+    modifier = g_strdup("");
+
+  if(strcmp(key_name, "Escape") == 0) {
+     g_free(w->keyaccel_string);
+     w->keyaccel_string = NULL;
+  } else if(w->keyaccel_string &&
+        strlen(w->keyaccel_string) + strlen(key_name) > 10) {
+     g_free(w->keyaccel_string);
+     w->keyaccel_string = g_strconcat(modifier, key_name, NULL);
   } else {
-    modifier = g_strdup_printf("\"");
+     gchar *p, *r;
+
+     p = w->keyaccel_string;
+     w->keyaccel_string = g_strconcat(modifier, key_name, NULL);
+     if(p) {
+        r = g_strconcat(p, w->keyaccel_string, NULL);
+        g_free(p);
+        g_free(w->keyaccel_string);
+        w->keyaccel_string = r;
+     }
   }
 
-  guile_string = g_strdup_printf("(press-key %s%s\")",
+  i_show_state(w, NULL);
+
+  guile_string = g_strdup_printf("(press-key \"%s%s\")",
                                  modifier, key_name);
 
 #if DEBUG 
@@ -142,14 +164,45 @@ g_keys_dump_keymap (void)
   return ret;
 }
 
-/*! \brief
+/*! \brief Clear the current key accelerator string
+ *
+ *  \par Function Description
+ *  This function clears the current keyboard accelerator
+ *  string in the status bar of the relevant toplevel.
+ *  Called after the action specifed by the keyboard
+ *  accelerator is executed and the associated timeout interval
+ *  has passed.
  *
+ *  \param [in] data a pointer to the toplevel
  */
+static gboolean clear_keyaccel_string(gpointer data)
+{
+  TOPLEVEL *w = global_window_current;
+
+  /* Find out if the toplevel is present... */
+  while(w->prev)
+    w = w->prev;
+
+  while(w) {
+    if(w == (TOPLEVEL *) data) {
+      /* ... it is, update its status bar */
+      g_free(w->keyaccel_string);
+      w->keyaccel_string = NULL;
+      i_show_state(w, NULL);
+      break;
+    }
+    w = w->next;
+  }
+
+  return FALSE;
+}
+
 #define DEFINE_G_KEYS(name)				\
 SCM g_keys_ ## name(void)				\
 {							\
-	i_callback_ ## name(global_window_current, 0, NULL);	\
-	return SCM_BOOL_T;				\
+   g_timeout_add(400, clear_keyaccel_string, global_window_current); \
+   i_callback_ ## name(global_window_current, 0, NULL); \
+   return SCM_BOOL_T;				\
 }
 
 /*! \brief test-comment
diff --git a/gschem/src/i_basic.c b/gschem/src/i_basic.c
index 3b41f49..f280345 100644
--- a/gschem/src/i_basic.c
+++ b/gschem/src/i_basic.c
@@ -184,6 +184,14 @@ void i_show_state(TOPLEVEL *w_current, const char *message)
 
   what_to_say = g_strjoinv(" - ", (gchar **) array + i);
 
+  if(w_current->keyaccel_string) {
+     gchar *p = what_to_say;
+
+     what_to_say = g_strdup_printf("%s \t\t %s", w_current->keyaccel_string,
+           what_to_say);
+     g_free(p);
+  }
+
   i_update_status(w_current, what_to_say);
   g_free(what_to_say);
 }
diff --git a/libgeda/include/struct.h b/libgeda/include/struct.h
index 82fdc26..e75b6ab 100644
--- a/libgeda/include/struct.h
+++ b/libgeda/include/struct.h
@@ -603,6 +603,9 @@ struct st_toplevel {
   /* backingstore pixmap */
   GdkPixmap *backingstore; 
 
+  /* used for visual feedback when pressing keyboard accelerators */
+  gchar *keyaccel_string;
+
   /* rc/user parameters */
   int graphic_color;
   int pin_color;
diff --git a/libgeda/src/s_toplevel.c b/libgeda/src/s_toplevel.c
index 0628945..889ea0b 100644
--- a/libgeda/src/s_toplevel.c
+++ b/libgeda/src/s_toplevel.c
@@ -264,6 +264,8 @@ TOPLEVEL *s_toplevel_new (void)
   toplevel->bounding_xor_gc = NULL;
   toplevel->bus_gc          = NULL;
 
+  toplevel->keyaccel_string = NULL;
+
   toplevel->backingstore = NULL;
 
   toplevel->graphic_color = 0;
-- 
1.5.2



_______________________________________________
geda-dev mailing list
geda-dev@moria.seul.org
http://www.seul.org/cgi-bin/mailman/listinfo/geda-dev