Button patch (Was: enhancing GTK visual quality)
- From: Damon Chaplin <damon helixcode com>
- To: Antonio Campos <acampos ceronet com>
- Cc: "gtk-devel-list gnome org" <gtk-devel-list gnome org>
- Subject: Button patch (Was: enhancing GTK visual quality)
- Date: Fri, 25 Aug 2000 15:47:00 +0100
Antonio Campos wrote:
>
> Derek Simkowiak wrote:
[snip]
> > -> 2) The long and interminable story of the buttons don't getting
> > -> depressed (visually) when the users click on them using the keyboard
> >
> > This has come up before.
> >
>
> Yes, but without any solutions.
> Does anybody have one?
I can't remember if there is already a patch floating around to do this.
But anyway, I've had a quick go and a patch is attached (for 1.2.7, though
it should be OK with 1.2.8).
It makes sure the button's state is ACTIVE in the "clicked" signal,
and uses a timeout callback to reset it.
This means that it will also happen if you call gtk_button_clicked(),
which we may not want. In that case we'd have to create another
signal to use as the activate_signal, and do all this there.
Damon
--- gtkbutton.h.orig Wed Feb 24 10:14:57 1999
+++ gtkbutton.h Fri Aug 25 14:48:41 2000
@@ -58,6 +58,9 @@
guint in_button : 1;
guint button_down : 1;
guint relief : 2;
+
+ /* Timeout ID used when the button is activated by the keyboard. */
+ guint activate_timeout_id;
};
struct _GtkButtonClass
--- gtkbutton.c.orig Tue May 11 03:31:08 1999
+++ gtkbutton.c Fri Aug 25 15:32:46 2000
@@ -36,6 +36,9 @@
#define DEFAULT_TOP_POS 4
#define DEFAULT_SPACING 7
+/* The timeout before the button is reset to the normal/prelight state after
+ being activated by the keyboard (or by a function call). */
+#define GTK_BUTTON_ACTIVATE_TIMEOUT 100
enum {
PRESSED,
@@ -55,6 +58,7 @@
static void gtk_button_class_init (GtkButtonClass *klass);
static void gtk_button_init (GtkButton *button);
+static void gtk_button_destroy (GtkObject *object);
static void gtk_button_set_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
@@ -92,9 +96,11 @@
GtkWidget *widget);
static void gtk_real_button_pressed (GtkButton *button);
static void gtk_real_button_released (GtkButton *button);
+static void gtk_real_button_clicked (GtkButton *button);
static void gtk_real_button_enter (GtkButton *button);
static void gtk_real_button_leave (GtkButton *button);
static GtkType gtk_button_child_type (GtkContainer *container);
+static gboolean gtk_button_activate_timeout_cb (gpointer data);
static GtkBinClass *parent_class = NULL;
@@ -181,6 +187,7 @@
gtk_object_class_add_signals (object_class, button_signals, LAST_SIGNAL);
+ object_class->destroy = gtk_button_destroy;
object_class->set_arg = gtk_button_set_arg;
object_class->get_arg = gtk_button_get_arg;
@@ -205,7 +212,7 @@
klass->pressed = gtk_real_button_pressed;
klass->released = gtk_real_button_released;
- klass->clicked = NULL;
+ klass->clicked = gtk_real_button_clicked;
klass->enter = gtk_real_button_enter;
klass->leave = gtk_real_button_leave;
}
@@ -222,6 +229,25 @@
button->relief = GTK_RELIEF_NORMAL;
}
+static void
+gtk_button_destroy (GtkObject *object)
+{
+ GtkButton *button;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GTK_IS_BUTTON (object));
+
+ button = GTK_BUTTON (object);
+
+ if (button->activate_timeout_id) {
+ g_source_remove (button->activate_timeout_id);
+ button->activate_timeout_id = 0;
+ }
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
static GtkType
gtk_button_child_type (GtkContainer *container)
{
@@ -865,6 +891,39 @@
}
static void
+gtk_real_button_clicked (GtkButton *button)
+{
+ gboolean add_timeout = FALSE;
+
+ g_return_if_fail (button != NULL);
+ g_return_if_fail (GTK_IS_BUTTON (button));
+
+ /* If the button wasn't active (e.g. it was activated by the keyboard)
+ we make it active here. */
+ if (GTK_WIDGET_STATE (button) != GTK_STATE_ACTIVE)
+ {
+ gtk_widget_set_state (GTK_WIDGET (button), GTK_STATE_ACTIVE);
+ /* We don't want to queue a draw, since if we do the button will only get
+ redrawn after the action has been performed, which may take time. */
+ gtk_widget_draw (GTK_WIDGET (button), NULL);
+ add_timeout = TRUE;
+ }
+
+ /* Remove any existing timeout. */
+ if (button->activate_timeout_id)
+ {
+ g_source_remove (button->activate_timeout_id);
+ add_timeout = TRUE;
+ }
+
+ /* Add a new timeout to restore the state. */
+ if (add_timeout)
+ button->activate_timeout_id = g_timeout_add (GTK_BUTTON_ACTIVATE_TIMEOUT,
+ gtk_button_activate_timeout_cb,
+ button);
+}
+
+static void
gtk_real_button_enter (GtkButton *button)
{
GtkStateType new_state;
@@ -893,3 +952,35 @@
gtk_widget_queue_draw (GTK_WIDGET (button));
}
}
+
+
+static gboolean
+gtk_button_activate_timeout_cb (gpointer data)
+{
+ GtkButton *button;
+ GtkStateType new_state;
+
+ GDK_THREADS_ENTER ();
+
+ button = GTK_BUTTON (data);
+
+ if (button->button_down && button->in_button)
+ new_state = GTK_STATE_ACTIVE;
+ else if (button->in_button)
+ new_state = GTK_STATE_PRELIGHT;
+ else
+ new_state = GTK_STATE_NORMAL;
+
+ if (GTK_WIDGET_STATE (button) != new_state)
+ {
+ gtk_widget_set_state (GTK_WIDGET (button), new_state);
+ gtk_widget_queue_draw (GTK_WIDGET (button));
+ }
+
+ button->activate_timeout_id = 0;
+
+ GDK_THREADS_LEAVE ();
+
+ return FALSE;
+}
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]