diff options
-rw-r--r-- | example/menus.c | 6 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/idoentrymenuitem.c | 232 | ||||
-rw-r--r-- | src/idoentrymenuitem.h | 60 |
4 files changed, 299 insertions, 1 deletions
diff --git a/example/menus.c b/example/menus.c index c27fc14..6cf0c75 100644 --- a/example/menus.c +++ b/example/menus.c @@ -1,6 +1,7 @@ #include <gtk/gtk.h> #include "idoscalemenuitem.h" +#include "idoentrymenuitem.h" int main (int argc, char *argv[]) @@ -37,7 +38,10 @@ main (int argc, char *argv[]) menuitem = gtk_menu_item_new_with_label ("Open"); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); - menuitem = ido_scale_menu_item_new_with_range ("Volume", 0, 100, 1); + //menuitem = ido_scale_menu_item_new_with_range ("Volume", 0, 100, 1); + //gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); + + menuitem = ido_entry_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); /* Add the menubar */ diff --git a/src/Makefile.am b/src/Makefile.am index 879c6d7..2f38a3b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,5 @@ sources_h = \ + idoentrymenuitem.h \ idoscalemenuitem.h INCLUDES = \ @@ -20,6 +21,7 @@ AM_CPPFLAGS = \ lib_LTLIBRARIES = libido-0.1.la libido_0_1_la_SOURCES = \ + idoentrymenuitem.c \ idoscalemenuitem.c libido_0_1_la_LIBADD = $(GTK_LIBS) diff --git a/src/idoentrymenuitem.c b/src/idoentrymenuitem.c new file mode 100644 index 0000000..1d5bd54 --- /dev/null +++ b/src/idoentrymenuitem.c @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2010 Canonical, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: + * Cody Russell <crussell@canonical.com> + */ + +#include "idoentrymenuitem.h" + +static void ido_entry_menu_item_select (GtkItem *item); +static void ido_entry_menu_item_deselect (GtkItem *item); +static gboolean ido_entry_menu_item_button_release (GtkWidget *widget, + GdkEventButton *event); +static gboolean ido_entry_menu_item_key_press (GtkWidget *widget, + GdkEventKey *event, + gpointer data); +static gboolean ido_entry_menu_item_button_press (GtkWidget *widget, + GdkEventButton *event); +static void ido_entry_menu_item_send_focus_change (GtkWidget *widget, + gboolean in); +static void entry_realized_cb (GtkWidget *widget, + IdoEntryMenuItem *item); +static void entry_move_focus_cb (GtkWidget *widget, + GtkDirectionType direction, + IdoEntryMenuItem *item); + +struct _IdoEntryMenuItemPrivate +{ + GtkWidget *entry; + gboolean selected; +}; + +G_DEFINE_TYPE (IdoEntryMenuItem, ido_entry_menu_item, GTK_TYPE_MENU_ITEM) + +#define IDO_ENTRY_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItemPrivate)) + +static void +ido_entry_menu_item_class_init (IdoEntryMenuItemClass *klass) +{ + GObjectClass *gobject_class; + GtkWidgetClass *widget_class; + GtkMenuItemClass *menu_item_class; + GtkItemClass *item_class; + + gobject_class = G_OBJECT_CLASS (klass); + widget_class = GTK_WIDGET_CLASS (klass); + menu_item_class = GTK_MENU_ITEM_CLASS (klass); + item_class = GTK_ITEM_CLASS (klass); + + widget_class->button_release_event = ido_entry_menu_item_button_release; + widget_class->button_press_event = ido_entry_menu_item_button_press; + + item_class->select = ido_entry_menu_item_select; + item_class->deselect = ido_entry_menu_item_deselect; + + menu_item_class->hide_on_activate = FALSE; + + g_type_class_add_private (gobject_class, sizeof (IdoEntryMenuItemPrivate)); +} + +static void +ido_entry_menu_item_init (IdoEntryMenuItem *item) +{ + IdoEntryMenuItemPrivate *priv; + + priv = item->priv = IDO_ENTRY_MENU_ITEM_GET_PRIVATE (item); + + priv->entry = gtk_entry_new (); + g_signal_connect (priv->entry, + "realize", + G_CALLBACK (entry_realized_cb), + item); + g_signal_connect (priv->entry, + "move-focus", + G_CALLBACK (entry_move_focus_cb), + item); + + gtk_widget_set_size_request (priv->entry, 100, -1); + + gtk_container_add (GTK_CONTAINER (item), priv->entry); + + gtk_widget_show (priv->entry); +} + +static gboolean +ido_entry_menu_item_button_release (GtkWidget *widget, + GdkEventButton *event) +{ + return TRUE; +} + +static gboolean +ido_entry_menu_item_key_press (GtkWidget *widget, + GdkEventKey *event, + gpointer data) +{ + IdoEntryMenuItem *menuitem = (IdoEntryMenuItem *)data; + + if (menuitem->priv->selected) + { + gtk_widget_event (menuitem->priv->entry, + (GdkEvent *)event); + } + + return FALSE; +} + +static void +ido_entry_menu_item_send_focus_change (GtkWidget *widget, + gboolean in) +{ + GdkEvent *event = gdk_event_new (GDK_FOCUS_CHANGE); + + g_object_ref (widget); + + if (in) + { + GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); + } + else + { + GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); + } + + event->focus_change.type = GDK_FOCUS_CHANGE; + event->focus_change.window = g_object_ref (widget->window); + event->focus_change.in = in; + + gtk_widget_event (widget, event); + + g_object_notify (G_OBJECT (widget), "has-focus"); + + g_object_unref (widget); + gdk_event_free (event); +} + +static gboolean +ido_entry_menu_item_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + GtkWidget *entry; + + entry = IDO_ENTRY_MENU_ITEM (widget)->priv->entry; + + if (entry->window != NULL) + { + gdk_window_raise (entry->window); + } + + if (!GTK_WIDGET_HAS_FOCUS (entry)) + { + gtk_widget_grab_focus (entry); + } + + return FALSE; +} + +static void +ido_entry_menu_item_select (GtkItem *item) +{ + IDO_ENTRY_MENU_ITEM (item)->priv->selected = TRUE; + + ido_entry_menu_item_send_focus_change (GTK_WIDGET (IDO_ENTRY_MENU_ITEM (item)->priv->entry), TRUE); +} + +static void +ido_entry_menu_item_deselect (GtkItem *item) +{ + IDO_ENTRY_MENU_ITEM (item)->priv->selected = FALSE; + + ido_entry_menu_item_send_focus_change (GTK_WIDGET (IDO_ENTRY_MENU_ITEM (item)->priv->entry), FALSE); +} + + +static void +entry_realized_cb (GtkWidget *widget, + IdoEntryMenuItem *item) +{ + if (widget->window != NULL) + { + gdk_window_raise (widget->window); + } + + g_signal_connect (GTK_WIDGET (item)->parent, + "key-press-event", + G_CALLBACK (ido_entry_menu_item_key_press), + item); + + ido_entry_menu_item_send_focus_change (widget, TRUE); +} + +static void +entry_move_focus_cb (GtkWidget *widget, + GtkDirectionType direction, + IdoEntryMenuItem *item) +{ + ido_entry_menu_item_send_focus_change (GTK_WIDGET (IDO_ENTRY_MENU_ITEM (item)->priv->entry), FALSE); + + g_signal_emit_by_name (item, + "move-focus", + GTK_DIR_TAB_FORWARD); +} + +/* Public API */ +GtkWidget * +ido_entry_menu_item_new (void) +{ + return g_object_new (IDO_TYPE_ENTRY_MENU_ITEM, NULL); +} + +GtkWidget * +ido_entry_menu_item_get_entry (IdoEntryMenuItem *item) +{ + g_return_val_if_fail (IDO_IS_ENTRY_MENU_ITEM (item), NULL); + + return item->priv->entry; +} diff --git a/src/idoentrymenuitem.h b/src/idoentrymenuitem.h new file mode 100644 index 0000000..f863f74 --- /dev/null +++ b/src/idoentrymenuitem.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010 Canonical, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: + * Cody Russell <crussell@canonical.com> + */ + +#ifndef __IDO_ENTRY_MENU_ITEM_H__ +#define __IDO_ENTRY_MENU_ITEM_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define IDO_TYPE_ENTRY_MENU_ITEM (ido_entry_menu_item_get_type ()) +#define IDO_ENTRY_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItem)) +#define IDO_ENTRY_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItemClass)) +#define IDO_IS_ENTRY_MENU_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IDO_TYPE_ENTRY_MENU_ITEM)) +#define IDO_IS_ENTRY_MENU_ITEM_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), IDO_TYPE_ENTRY_MENU_ITEM)) +#define IDO_ENTRY_MENU_ITEM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IDO_TYPE_ENTRY_MENU_ITEM, IdoEntryMenuItemClass)) + +typedef struct _IdoEntryMenuItem IdoEntryMenuItem; +typedef struct _IdoEntryMenuItemClass IdoEntryMenuItemClass; +typedef struct _IdoEntryMenuItemPrivate IdoEntryMenuItemPrivate; + +struct _IdoEntryMenuItem +{ + GtkMenuItem parent_instance; + + IdoEntryMenuItemPrivate *priv; +}; + +struct _IdoEntryMenuItemClass +{ + GtkMenuItemClass parent_class; +}; + +GType ido_entry_menu_item_get_type (void) G_GNUC_CONST; + +GtkWidget *ido_entry_menu_item_new (void); +GtkWidget *ido_entry_menu_item_get_entry (IdoEntryMenuItem *menuitem); + +G_END_DECLS + +#endif /* __IDO_ENTRY_MENU_ITEM_H__ */ |