Re: GtkNotebook accelerators.
- From: Alexander Larsson <alla lysator liu se>
- To: Owen Taylor <otaylor redhat com>
- Cc: <gtk-devel-list gnome org>
- Subject: Re: GtkNotebook accelerators.
- Date: Tue, 13 Mar 2001 13:56:37 +0100 (CET)
On 28 Feb 2001, Owen Taylor wrote:
> * I think we probably should avoid adding more append/prepend
> variants and simply stick to the convention that to prepend you
> insert with an index of 0, to append, you insert with and index of
> -1.
>
> * gtk_notebook_insert_page_label() should almost certainly
> be gtk_notebook_insert_page_accel() to correspond
> to gtk_button_new_accel()
>
> * But, more importantly, I'm not very happy with the way this
> works altogether - it's fiddly to set up, not flexible,
> and just more entry points than I like.
>
> I'm sort of coming to the conclusion here that we need
> to make some more changes to the way accelerators work in GTK+
> for 2.0 - it's something we've discussed some here, but
> were figuring we'd be able to punt to 2.2.
>
> Two issues in this area, that if we address, may provide some better
> resolution of this are:
>
> - If we use the scheme for label properties I suggested (or
> any scheme that allows setting of the underline), then how
> do you find out the accelerator? How is that accelerator
> hooked up.
>
> It probably at least necessary to store the accelerator
> for the label in some place that can be retrieved.
>
> - We need some way of indicating what widget a label is "for"
> both for accelerators, and for accessibility applications.
>
> So, perhaps it is best to hold off on this patch until we think
> about these things some more.
Do you thing there is enough time for this?
I made the changes you commented on, and added a way to block the
accelgroups of non-visible notebook pages. I've appended the patch.
I think this is good enough for 2.0. I've thought a bit about
generic handling of label accelerators, but i think we should punt that
work to 2.2.
/ Alex
Index: gtkaccelgroup.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkaccelgroup.c,v
retrieving revision 1.20
diff -u -p -r1.20 gtkaccelgroup.c
--- gtkaccelgroup.c 2000/10/25 22:34:11 1.20
+++ gtkaccelgroup.c 2001/03/13 12:48:56
@@ -118,6 +118,7 @@ gtk_accel_group_new (void)
accel_group->lock_count = 0;
accel_group->modifier_mask = gtk_accelerator_get_default_mod_mask ();
accel_group->attach_objects = NULL;
+ accel_group->blocked = FALSE;
return accel_group;
}
@@ -238,6 +239,23 @@ gtk_accel_group_unlock (GtkAccelGroup *
accel_group->lock_count -= 1;
}
+void
+gtk_accel_group_block (GtkAccelGroup *accel_group,
+ gboolean blocked)
+{
+ g_return_if_fail (accel_group != NULL);
+
+ accel_group->blocked = blocked;
+}
+
+gboolean
+gtk_accel_group_is_blocked (GtkAccelGroup *accel_group)
+{
+ g_return_if_fail (accel_group != NULL);
+
+ return accel_group->blocked;
+}
+
static GtkAccelEntry*
gtk_accel_group_lookup (GtkAccelGroup *accel_group,
guint accel_key,
@@ -260,6 +278,9 @@ gtk_accel_group_activate (GtkAccelGroup
GtkAccelEntry *entry;
g_return_val_if_fail (accel_group != NULL, FALSE);
+
+ if (accel_group->blocked)
+ return FALSE;
entry = gtk_accel_group_lookup (accel_group, accel_key, accel_mods);
if (entry && entry->signal_id &&
Index: gtkaccelgroup.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkaccelgroup.h,v
retrieving revision 1.9
diff -u -p -r1.9 gtkaccelgroup.h
--- gtkaccelgroup.h 2000/08/30 00:33:36 1.9
+++ gtkaccelgroup.h 2001/03/13 12:48:56
@@ -67,6 +67,7 @@ struct _GtkAccelGroup
guint lock_count;
GdkModifierType modifier_mask;
GSList *attach_objects;
+ guint blocked : 1;
};
struct _GtkAccelEntry
@@ -107,6 +108,10 @@ void gtk_accel_group_unlock (GtkAccelG
gboolean gtk_accel_groups_activate (GtkObject *object,
guint accel_key,
GdkModifierType accel_mods);
+void gtk_accel_group_block (GtkAccelGroup *accel_group,
+ gboolean blocked);
+gboolean gtk_accel_group_is_blocked (GtkAccelGroup *accel_group);
+
/* internal functions
*/
Index: gtknotebook.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtknotebook.c,v
retrieving revision 1.82
diff -u -p -r1.82 gtknotebook.c
--- gtknotebook.c 2001/03/09 13:28:25 1.82
+++ gtknotebook.c 2001/03/13 12:48:56
@@ -86,6 +86,8 @@ struct _GtkNotebookPage
GtkWidget *tab_label;
GtkWidget *menu_label;
+ GtkAccelGroup *accel_group;
+
guint default_menu : 1; /* If true, we create the menu label ourself */
guint default_tab : 1; /* If true, we create the tab label ourself */
guint expand : 1;
@@ -3264,7 +3266,10 @@ gtk_notebook_real_switch_page (GtkNotebo
if (notebook->cur_page && GTK_WIDGET_MAPPED (notebook->cur_page->child))
gtk_widget_unmap (notebook->cur_page->child);
-
+
+ if (notebook->cur_page && notebook->cur_page->accel_group)
+ gtk_accel_group_block (notebook->cur_page->accel_group, TRUE);
+
notebook->cur_page = page;
if (!notebook->focus_tab ||
@@ -3275,6 +3280,9 @@ gtk_notebook_real_switch_page (GtkNotebo
if (GTK_WIDGET_MAPPED (notebook))
gtk_widget_map (notebook->cur_page->child);
+ if (notebook->cur_page && notebook->cur_page->accel_group)
+ gtk_accel_group_block (notebook->cur_page->accel_group, FALSE);
+
gtk_widget_queue_resize (GTK_WIDGET (notebook));
}
@@ -3550,7 +3558,7 @@ gtk_notebook_append_page_menu (GtkNotebo
* @tab_label: the #GtkWidget to be used as the label for the page,
* or %NULL to use the default label, 'page N'.
*
- * Prepends a page to @noteobook.
+ * Prepends a page to @notebook.
**/
void
gtk_notebook_prepend_page (GtkNotebook *notebook,
@@ -3619,6 +3627,48 @@ gtk_notebook_insert_page (GtkNotebook *n
}
/**
+ * gtk_notebook_insert_page_accel:
+ * @notebook: a #GtkNotebook
+ * @child: the #GtkWidget to use as the contents of the page.
+ * @uline_label: the text of the label, use underscore to make
+ * keyboard accelerators.
+ * @accel_group: the accel group to place the keyboard accelerators
+ * in. May be null.
+ * @position: the index (starting at 0) at which to insert the page,
+ * or -1 to append the page after all other pages.
+ *
+ * Inserts a page to @notebook, with the specified label text.
+ **/
+void
+gtk_notebook_insert_page_accel (GtkNotebook *notebook,
+ GtkWidget *child,
+ const gchar *uline_label,
+ GtkAccelGroup *accel_group,
+ gint position)
+{
+ GtkWidget *tab_label;
+ guint keyval;
+
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+ g_return_if_fail (GTK_IS_WIDGET (child));
+ g_return_if_fail (uline_label != NULL);
+
+ tab_label = gtk_label_new (uline_label);
+ keyval = gtk_label_parse_uline (GTK_LABEL (tab_label),
+ uline_label);
+
+ gtk_notebook_insert_page_menu (notebook, child, tab_label, NULL, position);
+
+ if (accel_group)
+ gtk_notebook_set_tab_accel (notebook,
+ child,
+ keyval,
+ GDK_MOD1_MASK,
+ accel_group);
+
+}
+
+/**
* gtk_notebook_insert_page_menu:
* @notebook: a #GtkNotebook
* @child: the #GtkWidget to use as the contents of the page.
@@ -3661,6 +3711,7 @@ gtk_notebook_insert_page_menu (GtkNotebo
page->allocation.height = 0;
page->default_menu = FALSE;
page->default_tab = FALSE;
+ page->accel_group = NULL;
nchildren = g_list_length (notebook->children);
if ((position < 0) || (position > nchildren))
@@ -4360,6 +4411,138 @@ gtk_notebook_set_tab_label_text (GtkNote
if (tab_text)
tab_label = gtk_label_new (tab_text);
+ gtk_notebook_set_tab_label (notebook, child, tab_label);
+}
+
+static gboolean
+grab_focus_callback (GtkWidget *child, gpointer data)
+{
+ GtkNotebook *notebook = GTK_NOTEBOOK (data);
+ GtkNotebookPage *page;
+ GList *list;
+
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
+ return TRUE;
+
+ page = list->data;
+
+ gtk_notebook_switch_page (notebook, page, -1);
+ return TRUE;
+}
+
+/**
+ * gtk_notebook_set_tab_accel_group:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * @accel_group: an acceleration group
+ *
+ * This call binds an acceleration group to a particular notebook page.
+ * Only the acceleration group that belongs to the visible page is active,
+ * all the others are blocked.
+ **/
+void
+gtk_notebook_set_tab_accel_group (GtkNotebook *notebook,
+ GtkWidget *child,
+ GtkAccelGroup *accel_group)
+{
+ GtkNotebookPage *page;
+ GList *list;
+
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+ g_return_if_fail (child != NULL);
+
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
+ return;
+
+ page = list->data;
+
+ gtk_accel_group_ref (accel_group);
+
+ if (page->accel_group)
+ gtk_accel_group_unref (page->accel_group);
+
+ page->accel_group = accel_group;
+
+ gtk_accel_group_block (accel_group,
+ page != notebook->cur_page);
+}
+
+void
+gtk_notebook_set_tab_accel (GtkNotebook *notebook,
+ GtkWidget *child,
+ guint keyval,
+ guint modifiers,
+ GtkAccelGroup *accel_group)
+{
+ GList *list;
+ GtkNotebookPage *page;
+
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+ g_return_if_fail (child != NULL);
+
+ list = CHECK_FIND_CHILD (notebook, child);
+ if (!list)
+ return;
+
+ page = list->data;
+
+ /* Since we cannot add arguments to the signal emitted
+ * by the accelerator we misuse grab_focus of the child
+ * widget to get the child pointer.
+ */
+
+ gtk_widget_add_accelerator (child,
+ "grab_focus",
+ accel_group,
+ keyval,
+ modifiers,
+ GTK_ACCEL_LOCKED);
+
+ gtk_signal_connect (GTK_OBJECT (child),
+ "grab_focus",
+ (GtkSignalFunc) grab_focus_callback,
+ notebook);
+}
+
+/**
+ * gtk_notebook_set_tab_label_text_accel:
+ * @notebook: a #GtkNotebook
+ * @child: the page
+ * @uline_text: the label text, with underline
+ * @accel_group: The acceleration group to set the accelerator in
+ *
+ * Creates a new label and sets it as the tab label for the page
+ * containing @child. The label text is parsed looking for
+ * an underscore, and an accelerator <ALT>key is added that
+ * shows the page.
+ **/
+void
+gtk_notebook_set_tab_label_text_accel (GtkNotebook *notebook,
+ GtkWidget *child,
+ const gchar *uline_text,
+ GtkAccelGroup *accel_group)
+{
+ GtkWidget *tab_label = NULL;
+ guint keyval;
+
+ g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
+
+ if (uline_text)
+ {
+ tab_label = gtk_label_new (uline_text);
+ keyval = gtk_label_parse_uline (GTK_LABEL (tab_label),
+ uline_text);
+
+ if (accel_group)
+ gtk_notebook_set_tab_accel (notebook,
+ child,
+ keyval,
+ GDK_MOD1_MASK,
+ accel_group);
+
+ }
gtk_notebook_set_tab_label (notebook, child, tab_label);
}
Index: gtknotebook.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtknotebook.h,v
retrieving revision 1.23
diff -u -p -r1.23 gtknotebook.h
--- gtknotebook.h 2000/12/11 17:47:24 1.23
+++ gtknotebook.h 2001/03/13 12:48:57
@@ -92,34 +92,40 @@ struct _GtkNotebookClass
* Creation, insertion, deletion *
***********************************************************/
-GtkType gtk_notebook_get_type (void) G_GNUC_CONST;
-GtkWidget * gtk_notebook_new (void);
-void gtk_notebook_append_page (GtkNotebook *notebook,
- GtkWidget *child,
- GtkWidget *tab_label);
-void gtk_notebook_append_page_menu (GtkNotebook *notebook,
- GtkWidget *child,
- GtkWidget *tab_label,
- GtkWidget *menu_label);
-void gtk_notebook_prepend_page (GtkNotebook *notebook,
- GtkWidget *child,
- GtkWidget *tab_label);
-void gtk_notebook_prepend_page_menu (GtkNotebook *notebook,
- GtkWidget *child,
- GtkWidget *tab_label,
- GtkWidget *menu_label);
-void gtk_notebook_insert_page (GtkNotebook *notebook,
- GtkWidget *child,
- GtkWidget *tab_label,
- gint position);
-void gtk_notebook_insert_page_menu (GtkNotebook *notebook,
- GtkWidget *child,
- GtkWidget *tab_label,
- GtkWidget *menu_label,
- gint position);
-void gtk_notebook_remove_page (GtkNotebook *notebook,
- gint page_num);
+GtkType gtk_notebook_get_type (void) G_GNUC_CONST;
+GtkWidget *gtk_notebook_new (void);
+void gtk_notebook_append_page (GtkNotebook *notebook,
+ GtkWidget *child,
+ GtkWidget *tab_label);
+void gtk_notebook_append_page_menu (GtkNotebook *notebook,
+ GtkWidget *child,
+ GtkWidget *tab_label,
+ GtkWidget *menu_label);
+void gtk_notebook_prepend_page (GtkNotebook *notebook,
+ GtkWidget *child,
+ GtkWidget *tab_label);
+void gtk_notebook_prepend_page_menu (GtkNotebook *notebook,
+ GtkWidget *child,
+ GtkWidget *tab_label,
+ GtkWidget *menu_label);
+void gtk_notebook_insert_page (GtkNotebook *notebook,
+ GtkWidget *child,
+ GtkWidget *tab_label,
+ gint position);
+void gtk_notebook_insert_page_accel (GtkNotebook *notebook,
+ GtkWidget *child,
+ const gchar *uline_label,
+ GtkAccelGroup *accel_group,
+ gint position);
+void gtk_notebook_insert_page_menu (GtkNotebook *notebook,
+ GtkWidget *child,
+ GtkWidget *tab_label,
+ GtkWidget *menu_label,
+ gint position);
+void gtk_notebook_remove_page (GtkNotebook *notebook,
+ gint page_num);
+
/***********************************************************
* query, set current NoteebookPage *
***********************************************************/
@@ -174,6 +180,18 @@ void gtk_notebook_set_tab_label
void gtk_notebook_set_tab_label_text (GtkNotebook *notebook,
GtkWidget *child,
const gchar *tab_text);
+void gtk_notebook_set_tab_label_text_accel (GtkNotebook *notebook,
+ GtkWidget *child,
+ const gchar *uline_text,
+ GtkAccelGroup *accel_group);
+void gtk_notebook_set_tab_accel (GtkNotebook *notebook,
+ GtkWidget *child,
+ guint keyval,
+ guint modifiers,
+ GtkAccelGroup *accel_group);
+void gtk_notebook_set_tab_accel_group (GtkNotebook *notebook,
+ GtkWidget *child,
+ GtkAccelGroup *accel_group);
GtkWidget * gtk_notebook_get_menu_label (GtkNotebook *notebook,
GtkWidget *child);
void gtk_notebook_set_menu_label (GtkNotebook *notebook,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]