Commit ee2d7c45 authored by Owen Taylor's avatar Owen Taylor Committed by Owen Taylor

Support "optional" bindings. If a binding signal has a boolean return

Wed Jan 16 19:23:04 2002  Owen Taylor  <otaylor@redhat.com>

	* gtk/gtkbindings.c (gtk_binding_entry_activate):
	Support "optional" bindings. If a binding signal
	has a boolean return value, and returns FALSE it
	is as if it didn't exist all.

	* gtk/gtkbindings.c (binding_compose_params): Switch
	over to GValue.

	* gtk/gtknotebook.[ch]: Make the select_page() and
	change_current_page() signals only take effect when
	the focus is on the tab area so that key presses
	in children pass up to the toplevel correctly.
parent 226b2fa1
Wed Jan 16 19:23:04 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbindings.c (gtk_binding_entry_activate):
Support "optional" bindings. If a binding signal
has a boolean return value, and returns FALSE it
is as if it didn't exist all.
* gtk/gtkbindings.c (binding_compose_params): Switch
over to GValue.
* gtk/gtknotebook.[ch]: Make the select_page() and
change_current_page() signals only take effect when
the focus is on the tab area so that key presses
in children pass up to the toplevel correctly.
Wed Jan 16 12:16:37 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkoptionmenu.c (gtk_option_menu_size_request): Fix
calculation error in the (shouldn't happen) case where
option_menu->height < child_requisition.height. (Patch
from Jacob Berkman, #66969)
2002-01-15 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkenums.h (GtkMatchType): Deprecate. (#68183)
......
Wed Jan 16 19:23:04 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbindings.c (gtk_binding_entry_activate):
Support "optional" bindings. If a binding signal
has a boolean return value, and returns FALSE it
is as if it didn't exist all.
* gtk/gtkbindings.c (binding_compose_params): Switch
over to GValue.
* gtk/gtknotebook.[ch]: Make the select_page() and
change_current_page() signals only take effect when
the focus is on the tab area so that key presses
in children pass up to the toplevel correctly.
Wed Jan 16 12:16:37 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkoptionmenu.c (gtk_option_menu_size_request): Fix
calculation error in the (shouldn't happen) case where
option_menu->height < child_requisition.height. (Patch
from Jacob Berkman, #66969)
2002-01-15 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkenums.h (GtkMatchType): Deprecate. (#68183)
......
Wed Jan 16 19:23:04 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbindings.c (gtk_binding_entry_activate):
Support "optional" bindings. If a binding signal
has a boolean return value, and returns FALSE it
is as if it didn't exist all.
* gtk/gtkbindings.c (binding_compose_params): Switch
over to GValue.
* gtk/gtknotebook.[ch]: Make the select_page() and
change_current_page() signals only take effect when
the focus is on the tab area so that key presses
in children pass up to the toplevel correctly.
Wed Jan 16 12:16:37 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkoptionmenu.c (gtk_option_menu_size_request): Fix
calculation error in the (shouldn't happen) case where
option_menu->height < child_requisition.height. (Patch
from Jacob Berkman, #66969)
2002-01-15 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkenums.h (GtkMatchType): Deprecate. (#68183)
......
Wed Jan 16 19:23:04 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbindings.c (gtk_binding_entry_activate):
Support "optional" bindings. If a binding signal
has a boolean return value, and returns FALSE it
is as if it didn't exist all.
* gtk/gtkbindings.c (binding_compose_params): Switch
over to GValue.
* gtk/gtknotebook.[ch]: Make the select_page() and
change_current_page() signals only take effect when
the focus is on the tab area so that key presses
in children pass up to the toplevel correctly.
Wed Jan 16 12:16:37 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkoptionmenu.c (gtk_option_menu_size_request): Fix
calculation error in the (shouldn't happen) case where
option_menu->height < child_requisition.height. (Patch
from Jacob Berkman, #66969)
2002-01-15 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkenums.h (GtkMatchType): Deprecate. (#68183)
......
Wed Jan 16 19:23:04 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbindings.c (gtk_binding_entry_activate):
Support "optional" bindings. If a binding signal
has a boolean return value, and returns FALSE it
is as if it didn't exist all.
* gtk/gtkbindings.c (binding_compose_params): Switch
over to GValue.
* gtk/gtknotebook.[ch]: Make the select_page() and
change_current_page() signals only take effect when
the focus is on the tab area so that key presses
in children pass up to the toplevel correctly.
Wed Jan 16 12:16:37 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkoptionmenu.c (gtk_option_menu_size_request): Fix
calculation error in the (shouldn't happen) case where
option_menu->height < child_requisition.height. (Patch
from Jacob Berkman, #66969)
2002-01-15 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkenums.h (GtkMatchType): Deprecate. (#68183)
......
Wed Jan 16 19:23:04 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbindings.c (gtk_binding_entry_activate):
Support "optional" bindings. If a binding signal
has a boolean return value, and returns FALSE it
is as if it didn't exist all.
* gtk/gtkbindings.c (binding_compose_params): Switch
over to GValue.
* gtk/gtknotebook.[ch]: Make the select_page() and
change_current_page() signals only take effect when
the focus is on the tab area so that key presses
in children pass up to the toplevel correctly.
Wed Jan 16 12:16:37 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkoptionmenu.c (gtk_option_menu_size_request): Fix
calculation error in the (shouldn't happen) case where
option_menu->height < child_requisition.height. (Patch
from Jacob Berkman, #66969)
2002-01-15 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkenums.h (GtkMatchType): Deprecate. (#68183)
......
Wed Jan 16 19:23:04 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkbindings.c (gtk_binding_entry_activate):
Support "optional" bindings. If a binding signal
has a boolean return value, and returns FALSE it
is as if it didn't exist all.
* gtk/gtkbindings.c (binding_compose_params): Switch
over to GValue.
* gtk/gtknotebook.[ch]: Make the select_page() and
change_current_page() signals only take effect when
the focus is on the tab area so that key presses
in children pass up to the toplevel correctly.
Wed Jan 16 12:16:37 2002 Owen Taylor <otaylor@redhat.com>
* gtk/gtkoptionmenu.c (gtk_option_menu_size_request): Fix
calculation error in the (shouldn't happen) case where
option_menu->height < child_requisition.height. (Patch
from Jacob Berkman, #66969)
2002-01-15 Matthias Clasen <matthiasc@poet.de>
* gtk/gtkenums.h (GtkMatchType): Deprecate. (#68183)
......
......@@ -259,84 +259,109 @@ binding_ht_lookup_entry (GtkBindingSet *set,
}
static gboolean
binding_compose_params (GtkBindingArg *args,
binding_compose_params (GtkObject *object,
GtkBindingArg *args,
GSignalQuery *query,
GtkArg **params_p)
GValue **params_p)
{
GtkArg *params;
const GtkType *types;
GValue *params;
const GType *types;
guint i;
gboolean valid;
params = g_new0 (GtkArg, query->n_params);
params = g_new0 (GValue, query->n_params + 1);
*params_p = params;
/* The instance we emit on is the first object in the array
*/
g_value_init (params, G_TYPE_OBJECT);
g_value_set_object (params, G_OBJECT (object));
params++;
types = query->param_types;
valid = TRUE;
for (i = 0; i < query->n_params && valid; i++)
for (i = 1; i < query->n_params + 1 && valid; i++)
{
GtkType param_ftype;
GValue tmp_value = { 0, };
g_value_init (params, *types);
params->type = *types;
params->name = NULL;
param_ftype = GTK_FUNDAMENTAL_TYPE (params->type);
switch (GTK_FUNDAMENTAL_TYPE (args->arg_type))
switch (G_TYPE_FUNDAMENTAL (args->arg_type))
{
case GTK_TYPE_DOUBLE:
if (param_ftype == GTK_TYPE_FLOAT)
GTK_VALUE_FLOAT (*params) = args->d.double_data;
else if (param_ftype == GTK_TYPE_DOUBLE)
GTK_VALUE_DOUBLE (*params) = args->d.double_data;
else
valid = FALSE;
case G_TYPE_DOUBLE:
g_value_init (&tmp_value, G_TYPE_DOUBLE);
g_value_set_double (&tmp_value, args->d.double_data);
break;
case GTK_TYPE_LONG:
if (param_ftype == GTK_TYPE_BOOL &&
(args->d.long_data == 0 ||
args->d.long_data == 1))
GTK_VALUE_BOOL (*params) = args->d.long_data;
else if (param_ftype == GTK_TYPE_INT ||
param_ftype == GTK_TYPE_ENUM)
GTK_VALUE_INT (*params) = args->d.long_data;
else if ((param_ftype == GTK_TYPE_UINT ||
param_ftype == GTK_TYPE_FLAGS) &&
args->d.long_data >= 0)
GTK_VALUE_UINT (*params) = args->d.long_data;
else if (param_ftype == GTK_TYPE_LONG)
GTK_VALUE_LONG (*params) = args->d.long_data;
else if (param_ftype == GTK_TYPE_ULONG &&
args->d.long_data >= 0)
GTK_VALUE_ULONG (*params) = args->d.long_data;
else if (param_ftype == GTK_TYPE_FLOAT)
GTK_VALUE_FLOAT (*params) = args->d.long_data;
else if (param_ftype == GTK_TYPE_DOUBLE)
GTK_VALUE_DOUBLE (*params) = args->d.long_data;
else
valid = FALSE;
case G_TYPE_LONG:
g_value_init (&tmp_value, G_TYPE_LONG);
g_value_set_long (&tmp_value, args->d.long_data);
break;
case GTK_TYPE_STRING:
if (args->arg_type == GTK_TYPE_STRING &&
param_ftype == GTK_TYPE_STRING)
GTK_VALUE_STRING (*params) = args->d.string_data;
else if (args->arg_type == GTK_TYPE_IDENTIFIER &&
(param_ftype == GTK_TYPE_ENUM ||
param_ftype == GTK_TYPE_FLAGS))
case G_TYPE_STRING:
/* gtk_rc_parse_flags/enum() has fancier parsing for this; we can't call
* that since we don't have a GParamSpec, so just do something simple
*/
if (G_TYPE_FUNDAMENTAL (*types) == G_TYPE_ENUM)
{
GEnumClass *class = G_ENUM_CLASS (g_type_class_ref (*types));
valid = FALSE;
if (args->arg_type == GTK_TYPE_IDENTIFIER)
{
GEnumValue *enum_value = NULL;
enum_value = g_enum_get_value_by_name (class, args->d.string_data);
if (!enum_value)
enum_value = g_enum_get_value_by_nick (class, args->d.string_data);
if (enum_value)
{
g_value_set_enum (&tmp_value, enum_value->value);
valid = TRUE;
}
}
g_type_class_unref (class);
}
/* This is just a hack for compatibility with GTK+-1.2 where a string
* could be used for a single flag value / without the support for multiple
* values in gtk_rc_parse_flags(), this isn't very useful.
*/
else if (G_TYPE_FUNDAMENTAL (*types) == G_TYPE_FLAGS)
{
GtkEnumValue *value;
GFlagsClass *class = G_FLAGS_CLASS (g_type_class_ref (*types));
valid = FALSE;
if (args->arg_type == GTK_TYPE_IDENTIFIER)
{
GFlagsValue *flags_value = NULL;
flags_value = g_flags_get_value_by_name (class, args->d.string_data);
if (!flags_value)
flags_value = g_flags_get_value_by_nick (class, args->d.string_data);
if (flags_value)
{
g_value_set_flags (&tmp_value, flags_value->value);
valid = TRUE;
}
}
value = gtk_type_enum_find_value (params->type, args->d.string_data);
if (value)
GTK_VALUE_ENUM (*params) = value->value;
else
valid = FALSE;
g_type_class_unref (class);
}
else
valid = FALSE;
{
g_value_init (&tmp_value, G_TYPE_STRING);
g_value_set_static_string (params, args->d.string_data);
}
break;
default:
valid = FALSE;
break;
}
if (valid && !g_value_transform (&tmp_value, params))
valid = FALSE;
g_value_unset (&tmp_value);
types++;
params++;
args++;
......@@ -344,6 +369,11 @@ binding_compose_params (GtkBindingArg *args,
if (!valid)
{
guint j;
for (j = 0; j < i; j++)
g_value_unset (&(*params_p)[j]);
g_free (*params_p);
*params_p = NULL;
}
......@@ -351,26 +381,29 @@ binding_compose_params (GtkBindingArg *args,
return valid;
}
static void
gtk_binding_entry_activate (GtkBindingEntry *entry,
GtkObject *object)
static gboolean
gtk_binding_entry_activate (GtkBindingEntry *entry,
GtkObject *object)
{
GtkBindingSignal *sig;
gboolean old_emission;
gboolean handled = FALSE;
gint i;
old_emission = entry->in_emission;
entry->in_emission = TRUE;
gtk_object_ref (object);
g_object_ref (object);
for (sig = entry->signals; sig; sig = sig->next)
{
GSignalQuery query;
guint signal_id;
GtkArg *params = NULL;
GValue *params = NULL;
GValue return_val = { 0, };
gchar *accelerator = NULL;
signal_id = gtk_signal_lookup (sig->signal_name, GTK_OBJECT_TYPE (object));
signal_id = g_signal_lookup (sig->signal_name, G_OBJECT_TYPE (object));
if (!signal_id)
{
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
......@@ -379,15 +412,15 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
entry->binding_set->set_name,
accelerator,
sig->signal_name,
gtk_type_name (GTK_OBJECT_TYPE (object)));
g_type_name (G_OBJECT_TYPE (object)));
g_free (accelerator);
continue;
}
g_signal_query (signal_id, &query);
if (query.n_params != sig->n_args ||
query.return_type != G_TYPE_NONE ||
!binding_compose_params (sig->args, &query, &params))
(query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) ||
!binding_compose_params (object, sig->args, &query, &params))
{
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
......@@ -395,7 +428,7 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
entry->binding_set->set_name,
accelerator,
sig->signal_name,
gtk_type_name (GTK_OBJECT_TYPE (object)));
g_type_name (G_OBJECT_TYPE (object)));
}
else if (!(query.signal_flags & GTK_RUN_ACTION))
{
......@@ -405,24 +438,41 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
entry->binding_set->set_name,
accelerator,
sig->signal_name,
gtk_type_name (GTK_OBJECT_TYPE (object)));
g_type_name (G_OBJECT_TYPE (object)));
}
g_free (accelerator);
if (accelerator)
continue;
gtk_signal_emitv (object, signal_id, params);
if (query.return_type == G_TYPE_BOOLEAN)
g_value_init (&return_val, G_TYPE_BOOLEAN);
g_signal_emitv (params, signal_id, 0, &return_val);
if (query.return_type == G_TYPE_BOOLEAN)
{
if (g_value_get_boolean (&return_val))
handled = TRUE;
g_value_unset (&return_val);
}
else
handled = TRUE;
for (i = 0; i < query.n_params + 1; i++)
g_value_unset (&params[i]);
g_free (params);
if (entry->destroyed)
break;
}
gtk_object_unref (object);
g_object_unref (object);
entry->in_emission = old_emission;
if (entry->destroyed && !entry->in_emission)
binding_entry_free (entry);
return handled;
}
GtkBindingSet*
......@@ -506,11 +556,7 @@ gtk_binding_set_activate (GtkBindingSet *binding_set,
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
if (entry)
{
gtk_binding_entry_activate (entry, object);
return TRUE;
}
return gtk_binding_entry_activate (entry, object);
return FALSE;
}
......@@ -806,9 +852,8 @@ binding_match_activate (GSList *pspec_list,
binding_set = pspec->user_data;
gtk_binding_entry_activate (binding_set->current, object);
return TRUE;
if (gtk_binding_entry_activate (binding_set->current, object))
return TRUE;
}
}
......
......@@ -115,9 +115,9 @@ struct _GtkNotebookPage
static void gtk_notebook_class_init (GtkNotebookClass *klass);
static void gtk_notebook_init (GtkNotebook *notebook);
static void gtk_notebook_select_page (GtkNotebook *notebook,
gboolean move_focus);
static void gtk_notebook_focus_tab (GtkNotebook *notebook,
static gboolean gtk_notebook_select_page (GtkNotebook *notebook,
gboolean move_focus);
static gboolean gtk_notebook_focus_tab (GtkNotebook *notebook,
GtkNotebookTab type);
static void gtk_notebook_change_current_page (GtkNotebook *notebook,
gint offset);
......@@ -448,7 +448,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkNotebookClass, focus_tab),
NULL, NULL,
_gtk_marshal_VOID__ENUM,
_gtk_marshal_BOOLEAN__ENUM,
G_TYPE_NONE, 1,
GTK_TYPE_NOTEBOOK_TAB);
notebook_signals[SELECT_PAGE] =
......@@ -457,8 +457,8 @@ gtk_notebook_class_init (GtkNotebookClass *class)
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkNotebookClass, select_page),
NULL, NULL,
_gtk_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1,
_gtk_marshal_BOOLEAN__BOOLEAN,
G_TYPE_BOOLEAN, 1,
G_TYPE_BOOLEAN);
notebook_signals[CHANGE_CURRENT_PAGE] =
g_signal_new ("change_current_page",
......@@ -467,7 +467,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
G_STRUCT_OFFSET (GtkNotebookClass, change_current_page),
NULL, NULL,
gtk_marshal_VOID__INT,
G_TYPE_NONE, 1,
G_TYPE_BOOLEAN, 1,
G_TYPE_INT);
binding_set = gtk_binding_set_by_class (object_class);
......@@ -543,32 +543,45 @@ gtk_notebook_init (GtkNotebook *notebook)
notebook->have_visible_child = FALSE;
}
static void
static gboolean
gtk_notebook_select_page (GtkNotebook *notebook,
gboolean move_focus)
{
gtk_notebook_page_select (notebook, move_focus);
if (gtk_widget_is_focus (GTK_WIDGET (notebook)))
{
gtk_notebook_page_select (notebook, move_focus);
return TRUE;
}
else
return FALSE;
}
static void
static gboolean
gtk_notebook_focus_tab (GtkNotebook *notebook,
GtkNotebookTab type)
{
GList *list;
switch (type)
if (gtk_widget_is_focus (GTK_WIDGET (notebook)))
{
case GTK_NOTEBOOK_TAB_FIRST:
list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
if (list)
gtk_notebook_switch_focus_tab (notebook, list);
break;
case GTK_NOTEBOOK_TAB_LAST:
list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE);
if (list)
gtk_notebook_switch_focus_tab (notebook, list);
break;
switch (type)
{
case GTK_NOTEBOOK_TAB_FIRST:
list = gtk_notebook_search_page (notebook, NULL, STEP_NEXT, TRUE);
if (list)
gtk_notebook_switch_focus_tab (notebook, list);
break;
case GTK_NOTEBOOK_TAB_LAST:
list = gtk_notebook_search_page (notebook, NULL, STEP_PREV, TRUE);
if (list)
gtk_notebook_switch_focus_tab (notebook, list);
break;
}
return TRUE;
}
else
return FALSE;
}
static void
......@@ -3773,7 +3786,7 @@ gtk_notebook_mnemonic_activate_switch_page (GtkWidget *child,
{
GtkNotebookPage *page = list->data;
gtk_widget_grab_focus (notebook); /* Do this first to avoid focusing new page */
gtk_widget_grab_focus (GTK_WIDGET (notebook)); /* Do this first to avoid focusing new page */
gtk_notebook_switch_page (notebook, page, -1);
focus_tabs_in (notebook);
}
......
......@@ -94,9 +94,9 @@ struct _GtkNotebookClass
guint page_num);
/* Action signals for keybindings */
void (* select_page) (GtkNotebook *notebook,
gboolean (* select_page) (GtkNotebook *notebook,
gboolean move_focus);
void (* focus_tab) (GtkNotebook *notebook,
gboolean (* focus_tab) (GtkNotebook *notebook,
GtkNotebookTab type);
void (* change_current_page) (GtkNotebook *notebook,
gint offset);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment