Creating widgets with auto-repeat



Thanks to the people who pointed me in the right direction regarding my 
question about auto-repeating buttons.  The spinbutton source code 
did indeed gave me some ideas and I've hacked together the following "code" 
which I thought others might find useful as a starting point, particularly in
light of the fact that someone asked a similar question straight after me.

The auto-repeat starts after the button is held for 500ms, then goes through
two levels of speedup if the button is still pressed.

Perhaps someone with a bit more experience of this sort of thing could point
out a neat way to avoid all the globals here, so this code could be reused 
in a more generic way...  

Perosnally, I *like* globals... :-)


/******** CODE BEGINS *********************************/

#include <stdio.h>
#include <gtk/gtk.h>

#define REPEAT_STAGE0_DELAY 500
#define REPEAT_STAGE1_DELAY 50
#define REPEAT_STAGE2_DELAY 3

guint32 timer_id = 0;
gint timer_state = 0;
gint timer_count = 0;
gint value = 0;

/* Timer callback function! */
static gint timer_func ( void )
{

   /* Autorepeat state machine */
   switch (timer_state) {
      case 0: /* Enable slow auto-repeat */
         gtk_timeout_remove(timer_id);
         timer_id = gtk_timeout_add( REPEAT_STAGE1_DELAY, 
(GtkFunction)timer_func, NULL);
         timer_state = 1;
         timer_count = 0;
         break;
      case 1: /* Check if it's time for fast repeat yet */
         if (timer_count++ > 50)
            timer_state = 2;
         break;
      case 2: /* Start fast auto-repeat */
         gtk_timeout_remove(timer_id);
         timer_id = gtk_timeout_add( REPEAT_STAGE2_DELAY, 
(GtkFunction)timer_func, NULL);
         timer_state = 3;
         break;
      default:
         break;
   }

   /* Increment value */
   printf("value: %d\n", value++);

   return TRUE;

}

void button_press_proc( GtkWidget *widget, gpointer data )
{

   /* Increment value */
   printf("VALUE: %d\n", value++);

   /* Remove an existing timer */
   if (timer_id)
      gtk_timeout_remove(timer_id);

   /* Setup a timer */
   timer_id = gtk_timeout_add( REPEAT_STAGE0_DELAY, (GtkFunction)timer_func, 
NULL);
   timer_state = 0;

}

void button_release_proc( GtkWidget *widget, gpointer data )
{

   /* Remove timer */
   gtk_timeout_remove(timer_id);
   timer_id = 0;
   timer_state = 0;

}

int main( int   argc, char *argv[] )
{
   GtkWidget *window;
   GtkWidget *button;

   gtk_init(&argc, &argv);
   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
   gtk_container_set_border_width (GTK_CONTAINER (window), 10);
   button = gtk_button_new_with_label (" INCREMENT ");
   gtk_signal_connect (GTK_OBJECT (button), "button_press_event",
                       GTK_SIGNAL_FUNC (button_press_proc), NULL);
   gtk_signal_connect (GTK_OBJECT (button), "button_release_event",
                       GTK_SIGNAL_FUNC (button_release_proc), NULL);
   gtk_container_add (GTK_CONTAINER (window), button);
   gtk_widget_show (button);
   gtk_widget_show (window);
   gtk_main ();

   return(0);
}

/***************** END OF CODE *********************************/

-- 
David J. Singer
doc deadvirgins org uk
"Time flies like an arrow, fruit flies like a banana"



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