summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2001-03-06 15:51:10 +0000
committerOwen Taylor <otaylor@src.gnome.org>2001-03-06 15:51:10 +0000
commit71aa1161b309ea0ad4e9776ebb554b920071c298 (patch)
tree7ab66033bd99fdab00cd955a50b3127090ed30fd /gtk
parent96f9c875ee1445c2e4a2b62ec98b76505adc2728 (diff)
downloadgtk+-71aa1161b309ea0ad4e9776ebb554b920071c298.tar.gz
Add animation of activation by, on activate, pressing the button, and
Tue Mar 6 10:45:45 2001 Owen Taylor <otaylor@redhat.com> * gtk/gtkbutton.c: Add animation of activation by, on activate, pressing the button, and adding a timeout that releases the button after 250ms or on key release and emits ::clicked. (#51501) * gtk/gtkdialog.c: Bit of a hack - for buttons in the action area, we connect to ::clicked instead of ::activate so the dialog stays up through the animation. Mon Mar 5 16:38:15 2001 Owen Taylor <otaylor@redhat.com> * gtk/gtkmenushell.c (gtk_menu_shell_enter_notify): Only check the ignore_enter flag for the menu shell that the item is actually a child of, not for attached submenus. (#51536)
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkbutton.c120
-rw-r--r--gtk/gtkbutton.h3
-rw-r--r--gtk/gtkdialog.c13
-rw-r--r--gtk/gtkmenushell.c5
4 files changed, 133 insertions, 8 deletions
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index d756af1ba5..ecdd7b5a0e 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -39,6 +39,10 @@
#define DEFAULT_TOP_POS 4
#define DEFAULT_SPACING 7
+/* Time out before giving up on getting a key release when animatng
+ * the close button.
+ */
+#define ACTIVATE_TIMEOUT 250
enum {
PRESSED,
@@ -46,6 +50,7 @@ enum {
CLICKED,
ENTER,
LEAVE,
+ ACTIVATE,
LAST_SIGNAL
};
@@ -55,8 +60,6 @@ enum {
ARG_RELIEF
};
-
-
static void gtk_button_class_init (GtkButtonClass *klass);
static void gtk_button_init (GtkButton *button);
static void gtk_button_set_arg (GtkObject *object,
@@ -66,6 +69,7 @@ static void gtk_button_get_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void gtk_button_realize (GtkWidget *widget);
+static void gtk_button_unrealize (GtkWidget *widget);
static void gtk_button_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_button_size_allocate (GtkWidget *widget,
@@ -78,6 +82,8 @@ static gint gtk_button_button_press (GtkWidget *widget,
GdkEventButton *event);
static gint gtk_button_button_release (GtkWidget *widget,
GdkEventButton *event);
+static gint gtk_button_key_release (GtkWidget *widget,
+ GdkEventKey *event);
static gint gtk_button_enter_notify (GtkWidget *widget,
GdkEventCrossing *event);
static gint gtk_button_leave_notify (GtkWidget *widget,
@@ -90,8 +96,11 @@ static void gtk_real_button_pressed (GtkButton *button);
static void gtk_real_button_released (GtkButton *button);
static void gtk_real_button_enter (GtkButton *button);
static void gtk_real_button_leave (GtkButton *button);
+static void gtk_real_button_activate (GtkButton *button);
static GtkType gtk_button_child_type (GtkContainer *container);
+static void gtk_button_finish_activate (GtkButton *button,
+ gboolean do_it);
static GtkBinClass *parent_class = NULL;
static guint button_signals[LAST_SIGNAL] = { 0 };
@@ -141,11 +150,13 @@ gtk_button_class_init (GtkButtonClass *klass)
object_class->get_arg = gtk_button_get_arg;
widget_class->realize = gtk_button_realize;
+ widget_class->unrealize = gtk_button_unrealize;
widget_class->size_request = gtk_button_size_request;
widget_class->size_allocate = gtk_button_size_allocate;
widget_class->expose_event = gtk_button_expose;
widget_class->button_press_event = gtk_button_button_press;
widget_class->button_release_event = gtk_button_button_release;
+ widget_class->key_release_event = gtk_button_key_release;
widget_class->enter_notify_event = gtk_button_enter_notify;
widget_class->leave_notify_event = gtk_button_leave_notify;
@@ -158,6 +169,7 @@ gtk_button_class_init (GtkButtonClass *klass)
klass->clicked = NULL;
klass->enter = gtk_real_button_enter;
klass->leave = gtk_real_button_leave;
+ klass->activate = gtk_real_button_activate;
gtk_object_add_arg_type ("GtkButton::label", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_LABEL);
gtk_object_add_arg_type ("GtkButton::relief", GTK_TYPE_RELIEF_STYLE, GTK_ARG_READWRITE, ARG_RELIEF);
@@ -183,7 +195,6 @@ gtk_button_class_init (GtkButtonClass *klass)
GTK_SIGNAL_OFFSET (GtkButtonClass, clicked),
gtk_marshal_VOID__VOID,
GTK_TYPE_NONE, 0);
- widget_class->activate_signal = button_signals[CLICKED];
button_signals[ENTER] =
gtk_signal_new ("enter",
GTK_RUN_FIRST,
@@ -198,6 +209,14 @@ gtk_button_class_init (GtkButtonClass *klass)
GTK_SIGNAL_OFFSET (GtkButtonClass, leave),
gtk_marshal_VOID__VOID,
GTK_TYPE_NONE, 0);
+ button_signals[ACTIVATE] =
+ gtk_signal_new ("activate",
+ GTK_RUN_FIRST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkButtonClass, activate),
+ gtk_marshal_VOID__VOID,
+ GTK_TYPE_NONE, 0);
+ widget_class->activate_signal = button_signals[ACTIVATE];
}
static void
@@ -494,6 +513,17 @@ gtk_button_realize (GtkWidget *widget)
}
static void
+gtk_button_unrealize (GtkWidget *widget)
+{
+ GtkButton *button = GTK_BUTTON (widget);
+
+ if (button->activate_timeout)
+ gtk_button_finish_activate (button, FALSE);
+
+ GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+}
+
+static void
gtk_button_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
@@ -749,6 +779,23 @@ gtk_button_button_release (GtkWidget *widget,
return TRUE;
}
+static gboolean
+gtk_button_key_release (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ GtkButton *button = GTK_BUTTON (widget);
+
+ if (button->activate_timeout)
+ {
+ gtk_button_finish_activate (button, TRUE);
+ return TRUE;
+ }
+ else if (GTK_WIDGET_CLASS (parent_class)->key_release_event)
+ return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
+ else
+ return FALSE;
+}
+
static gint
gtk_button_enter_notify (GtkWidget *widget,
GdkEventCrossing *event)
@@ -831,6 +878,9 @@ gtk_real_button_pressed (GtkButton *button)
g_return_if_fail (button != NULL);
g_return_if_fail (GTK_IS_BUTTON (button));
+ if (button->activate_timeout)
+ return;
+
button->button_down = TRUE;
new_state = (button->in_button ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL);
@@ -854,6 +904,9 @@ gtk_real_button_released (GtkButton *button)
{
button->button_down = FALSE;
+ if (button->activate_timeout)
+ return;
+
if (button->in_button)
gtk_button_clicked (button);
@@ -880,6 +933,9 @@ gtk_real_button_enter (GtkButton *button)
new_state = (button->button_down ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT);
+ if (button->activate_timeout)
+ return;
+
if (GTK_WIDGET_STATE (button) != new_state)
{
gtk_widget_set_state (GTK_WIDGET (button), new_state);
@@ -892,10 +948,66 @@ gtk_real_button_leave (GtkButton *button)
{
g_return_if_fail (button != NULL);
g_return_if_fail (GTK_IS_BUTTON (button));
-
+
+ if (button->activate_timeout)
+ return;
+
if (GTK_WIDGET_STATE (button) != GTK_STATE_NORMAL)
{
gtk_widget_set_state (GTK_WIDGET (button), GTK_STATE_NORMAL);
gtk_widget_queue_draw (GTK_WIDGET (button));
}
}
+
+static gboolean
+button_activate_timeout (gpointer data)
+{
+ gtk_button_finish_activate (data, TRUE);
+
+ return FALSE;
+}
+
+static void
+gtk_real_button_activate (GtkButton *button)
+{
+ GtkWidget *widget = GTK_WIDGET (button);
+
+ g_return_if_fail (button != NULL);
+ g_return_if_fail (GTK_IS_BUTTON (button));
+
+ if (GTK_WIDGET_REALIZED (button) && !button->activate_timeout)
+ {
+ if (gdk_keyboard_grab (widget->window, TRUE,
+ gtk_get_current_event_time ()) == 0)
+ {
+ gtk_grab_add (widget);
+
+ button->activate_timeout = g_timeout_add (ACTIVATE_TIMEOUT,
+ button_activate_timeout,
+ button);
+ button->button_down = TRUE;
+ gtk_widget_set_state (widget, GTK_STATE_ACTIVE);
+ }
+ }
+}
+
+static void
+gtk_button_finish_activate (GtkButton *button,
+ gboolean do_it)
+{
+ GtkWidget *widget = GTK_WIDGET (button);
+
+ g_source_remove (button->activate_timeout);
+ button->activate_timeout = 0;
+
+ gdk_keyboard_ungrab (gtk_get_current_event_time ());
+ gtk_grab_remove (widget);
+
+ button->button_down = FALSE;
+ gtk_widget_set_state (GTK_WIDGET (button),
+ button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
+
+ if (do_it)
+ gtk_button_clicked (button);
+}
+
diff --git a/gtk/gtkbutton.h b/gtk/gtkbutton.h
index 0d8c676d09..553813994c 100644
--- a/gtk/gtkbutton.h
+++ b/gtk/gtkbutton.h
@@ -56,6 +56,8 @@ struct _GtkButton
* use GTK_BIN (button)->child instead
*/;
+ guint activate_timeout;
+
guint in_button : 1;
guint button_down : 1;
guint relief : 2;
@@ -70,6 +72,7 @@ struct _GtkButtonClass
void (* clicked) (GtkButton *button);
void (* enter) (GtkButton *button);
void (* leave) (GtkButton *button);
+ void (* activate) (GtkButton *button);
};
diff --git a/gtk/gtkdialog.c b/gtk/gtkdialog.c
index 85c3432bcd..1742f56780 100644
--- a/gtk/gtkdialog.c
+++ b/gtk/gtkdialog.c
@@ -340,6 +340,7 @@ gtk_dialog_add_action_widget (GtkDialog *dialog,
gint response_id)
{
ResponseData *ad;
+ gint signal_id = 0;
g_return_if_fail (GTK_IS_DIALOG (dialog));
g_return_if_fail (GTK_IS_WIDGET (child));
@@ -348,10 +349,16 @@ gtk_dialog_add_action_widget (GtkDialog *dialog,
ad->response_id = response_id;
- if (GTK_WIDGET_GET_CLASS (child)->activate_signal != 0)
+ if (GTK_IS_BUTTON (child))
{
- const gchar* name =
- gtk_signal_name (GTK_WIDGET_GET_CLASS (child)->activate_signal);
+ signal_id = g_signal_lookup ("clicked", GTK_TYPE_BUTTON);
+ }
+ else
+ signal_id = GTK_WIDGET_GET_CLASS (child)->activate_signal != 0;
+
+ if (signal_id)
+ {
+ const gchar* name = gtk_signal_name (signal_id);
gtk_signal_connect_while_alive (GTK_OBJECT (child),
name,
diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c
index 96765471f4..a59acf4a28 100644
--- a/gtk/gtkmenushell.c
+++ b/gtk/gtkmenushell.c
@@ -585,7 +585,7 @@ gtk_menu_shell_enter_notify (GtkWidget *widget,
menu_shell = GTK_MENU_SHELL (widget);
- if (menu_shell->active && !menu_shell->ignore_enter)
+ if (menu_shell->active)
{
menu_item = gtk_get_event_widget ((GdkEvent*) event);
@@ -596,6 +596,9 @@ gtk_menu_shell_enter_notify (GtkWidget *widget,
(menu_shell->active_menu_item != menu_item) &&
GTK_IS_MENU_ITEM (menu_item))
{
+ if (menu_shell->ignore_enter)
+ return TRUE;
+
if ((event->detail != GDK_NOTIFY_INFERIOR) &&
(GTK_WIDGET_STATE (menu_item) != GTK_STATE_PRELIGHT))
{