diff options
Diffstat (limited to 'app/wlib/gtklib/button.c')
-rw-r--r-- | app/wlib/gtklib/button.c | 157 |
1 files changed, 138 insertions, 19 deletions
diff --git a/app/wlib/gtklib/button.c b/app/wlib/gtklib/button.c index 51106c8..9a8ec77 100644 --- a/app/wlib/gtklib/button.c +++ b/app/wlib/gtklib/button.c @@ -57,6 +57,13 @@ void wButtonSetBusy(wButton_p bb, int value) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bb->widget), value); bb->recursion--; bb->busy = value; + if (!value) { + if (bb->timer_id) { + g_source_remove(bb->timer_id); + bb->timer_id = 0; + } + bb->timer_state = -1; + } } /** @@ -148,9 +155,10 @@ void wlibButtonDoAction( } } + /** * Signal handler for button push - * \param widget IN the widget + * \param widget IN the widget or NULL for autorepeat * \param value IN the button handle (same as widget???) */ @@ -168,17 +176,124 @@ static void pushButt( return; } + wlibStringUpdate(); if (b->action) { b->action(b->data); } - if (!b->busy) { - b->recursion++; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b->widget), FALSE); - b->recursion--; - } + +} + +#define REPEAT_STAGE0_DELAY 500 +#define REPEAT_STAGE1_DELAY 150 +#define REPEAT_STAGE2_DELAY 100 + +/* Timer callback function! */ +static int timer_func ( void * data) +{ + wButton_p bb = (wButton_p)data; + if (bb->timer_id == 0) { + bb->timer_state = -1; + return FALSE; + } + /* Autorepeat state machine */ + switch (bb->timer_state) { + case 0: /* Enable slow auto-repeat */ + g_source_remove(bb->timer_id); + bb->timer_id = 0; + bb->timer_state = 1; + bb->timer_id = g_timeout_add( REPEAT_STAGE1_DELAY, timer_func, bb); + bb->timer_count = 0; + break; + case 1: /* Check if it's time for fast repeat yet */ + if (bb->timer_count++ > 10) + bb->timer_state = 2; + break; + case 2: /* Start fast auto-repeat */ + g_source_remove(bb->timer_id); + bb->timer_id = 0; + bb->timer_state = 3; + bb->timer_id = g_timeout_add( REPEAT_STAGE2_DELAY, timer_func, bb); + break; + case 3: + break; + default: + g_source_remove(bb->timer_id); + bb->timer_id = 0; + bb->timer_state = -1; + return FALSE; + break; + } + + pushButt(NULL,bb); + + return TRUE; + +} + +static gint pressButt( + GtkWidget *widget, + GdkEventButton *event, + wButton_p bb) { + + if ( debugWindow >= 1 ) + printf( "buttonPress: %s\n", bb->labelStr ); + if (bb->recursion) { + return TRUE; + + } + + + if (bb->option & BO_REPEAT) { + /* Remove an existing timer */ + if (bb->timer_id) + g_source_remove(bb->timer_id); + + /* Setup a timer */ + bb->timer_id = g_timeout_add( REPEAT_STAGE0_DELAY, timer_func, bb); + bb->timer_state = 0; + + } + + if (!bb->busy) { + bb->recursion++; + int sensitive = gtk_widget_get_sensitive (GTK_WIDGET(bb->widget)); + if (sensitive) + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bb->widget), TRUE); + bb->recursion--; + } + + + return TRUE; + +} + +static gint releaseButt( + GtkWidget *widget, + GdkEventButton *event, + wButton_p bb) { + + if ( debugWindow >= 1 ) + printf( "buttonRelease: %s\n", bb->labelStr ); + /* Remove any existing timer */ + if (bb->timer_id) { + g_source_remove(bb->timer_id); + bb->timer_id = 0; + } + + bb->timer_state = -1; + + pushButt(widget,bb); //Do here to simulate "clicked" + + if (!bb->busy) { + bb->recursion++; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bb->widget), FALSE); + bb->recursion--; + } + return TRUE; } + /** * Called after expose event default hander - allows the button to be outlined */ @@ -208,12 +323,12 @@ static wBool_t exposeButt( wButton_p wButtonCreate( wWin_p parent, - wPos_t x, - wPos_t y, + wWinPix_t x, + wWinPix_t y, const char * helpStr, const char * labelStr, long option, - wPos_t width, + wWinPix_t width, wButtonCallBack_p action, void * data) { @@ -227,8 +342,12 @@ wButton_p wButtonCreate( wlibComputePos((wControl_p)b); b->widget = gtk_toggle_button_new(); - g_signal_connect(GTK_OBJECT(b->widget), "clicked", - G_CALLBACK(pushButt), b); + g_signal_connect(GTK_OBJECT(b->widget), "button_press_event", + G_CALLBACK(pressButt), b); + g_signal_connect(GTK_OBJECT(b->widget), "button_release_event", + G_CALLBACK(releaseButt), b); + //g_signal_connect(GTK_OBJECT(b->widget), "clicked", + // G_CALLBACK(pushButt), b); g_signal_connect_after(GTK_OBJECT(b->widget), "expose-event", G_CALLBACK(exposeButt), b); if (width > 0) { @@ -476,18 +595,18 @@ static void choiceRepaint( wChoice_p wRadioCreate( wWin_p parent, - wPos_t x, - wPos_t y, + wWinPix_t x, + wWinPix_t y, const char * helpStr, const char * labelStr, long option, - const char **labels, + const char * const *labels, long *valueP, wChoiceCallBack_p action, void *data) { wChoice_p b; - const char ** label; + const char * const * label; GtkWidget *butt0=NULL, *butt; if ((option & BC_NOBORDER)==0) { @@ -584,18 +703,18 @@ wChoice_p wRadioCreate( wChoice_p wToggleCreate( wWin_p parent, - wPos_t x, - wPos_t y, + wWinPix_t x, + wWinPix_t y, const char * helpStr, const char * labelStr, long option, - const char **labels, + const char * const * labels, long *valueP, wChoiceCallBack_p action, void *data) { wChoice_p b; - const char ** label; + const char * const * label; if ((option & BC_NOBORDER)==0) { if (x>=0) { |