summaryrefslogtreecommitdiff
path: root/app/wlib/gtklib/button.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/wlib/gtklib/button.c')
-rw-r--r--app/wlib/gtklib/button.c157
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) {