From 7192fa38f9edeb3fe9d42f7d266e1d55ad1abdd8 Mon Sep 17 00:00:00 2001 From: Christian Dywan Date: Tue, 21 Jul 2009 23:57:57 +0200 Subject: [PATCH] Implement "minimized" views, with a context menu option The flag is saved as meta data of the proxy item. A new signal meta-data-changed is implemented in KatzeItem to allow the view to update the tab state as the meta data value is changed. --- katze/katze-item.c | 32 ++++++++++++++++++-- midori/midori-view.c | 72 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/katze/katze-item.c b/katze/katze-item.c index d96490cb..a63afd45 100644 --- a/katze/katze-item.c +++ b/katze/katze-item.c @@ -24,7 +24,7 @@ * several commonly needed properties. */ -G_DEFINE_TYPE (KatzeItem, katze_item, G_TYPE_OBJECT) +G_DEFINE_TYPE (KatzeItem, katze_item, G_TYPE_OBJECT); enum { @@ -39,6 +39,14 @@ enum PROP_PARENT }; +enum { + META_DATA_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + static void katze_item_finalize (GObject* object); @@ -60,6 +68,26 @@ katze_item_class_init (KatzeItemClass* class) GObjectClass* gobject_class; GParamFlags flags; + /** + * KatzeItem::meta-data-changed: + * @item: the object on which the signal is emitted + * @key: the key that changed + * + * Emitted when a meta data value was changed. + * + * Since: 0.1.9 + */ + signals[META_DATA_CHANGED] = g_signal_new ( + "meta-data-changed", + G_TYPE_FROM_CLASS (class), + (GSignalFlags)(G_SIGNAL_RUN_LAST), + 0, + 0, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, + G_TYPE_STRING); + gobject_class = G_OBJECT_CLASS (class); gobject_class->finalize = katze_item_finalize; gobject_class->set_property = katze_item_set_property; @@ -482,7 +510,7 @@ katze_item_set_meta_data_value (KatzeItem* item, g_hash_table_insert (item->metadata, g_strdup (&key[7]), value); else g_hash_table_insert (item->metadata, g_strdup (key), value); - /* TODO: Emit meta-key-changed */ + g_signal_emit (item, signals[META_DATA_CHANGED], 0, key); } /** diff --git a/midori/midori-view.c b/midori/midori-view.c index a8886d43..069e5ab4 100644 --- a/midori/midori-view.c +++ b/midori/midori-view.c @@ -52,6 +52,11 @@ midori_view_get_snapshot (MidoriView* view, gint width, gint height); +static void +midori_view_item_meta_data_changed (KatzeItem* item, + const gchar* key, + MidoriView* view); + struct _MidoriView { GtkScrolledWindow parent_instance; @@ -62,6 +67,7 @@ struct _MidoriView GdkPixbuf* icon; gdouble progress; MidoriLoadStatus load_status; + gboolean minimized; gchar* statusbar_text; gchar* link_uri; gboolean has_selection; @@ -144,6 +150,7 @@ enum PROP_ICON, PROP_LOAD_STATUS, PROP_PROGRESS, + PROP_MINIMIZED, PROP_ZOOM_LEVEL, PROP_NEWS_FEEDS, PROP_STATUSBAR_TEXT, @@ -464,6 +471,26 @@ midori_view_class_init (MidoriViewClass* class) 0.0, 1.0, 0.0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + /** + * MidoriView:minimized: + * + * Whether the view is minimized or in normal state. + * + * Minimizing a view indicates that only the icon should + * be advertised rather than the full blown tab label and + * it might otherwise be presented specially. + * + * Since: 0.1.8 + */ + g_object_class_install_property (gobject_class, + PROP_MINIMIZED, + g_param_spec_boolean ( + "minimized", + "Minimized", + "Whether the view is minimized or in normal state", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_ZOOM_LEVEL, g_param_spec_float ( @@ -1596,6 +1623,7 @@ midori_view_init (MidoriView* view) GTK_ICON_SIZE_MENU, NULL); view->progress = 0.0; view->load_status = MIDORI_LOAD_FINISHED; + view->minimized = FALSE; view->statusbar_text = NULL; view->link_uri = NULL; view->selected_text = NULL; @@ -1621,6 +1649,9 @@ midori_view_finalize (GObject* object) if (view->settings) g_signal_handlers_disconnect_by_func (view->settings, midori_view_settings_notify_cb, view); + if (view->item) + g_signal_handlers_disconnect_by_func (view->item, + midori_view_item_meta_data_changed, view); katze_assign (view->uri, NULL); katze_assign (view->title, NULL); @@ -1657,6 +1688,20 @@ midori_view_set_property (GObject* object, katze_assign (view->title, g_value_dup_string (value)); midori_view_update_title (view); break; + case PROP_MINIMIZED: + view->minimized = g_value_get_boolean (value); + if (view->item) + { + g_signal_handlers_block_by_func (view->item, + midori_view_item_meta_data_changed, view); + katze_item_set_meta_integer (view->item, "minimized", + view->minimized ? 1 : -1); + g_signal_handlers_unblock_by_func (view->item, + midori_view_item_meta_data_changed, view); + } + if (view->tab_label) + sokoke_widget_set_visible (view->tab_title, !view->minimized); + break; case PROP_ZOOM_LEVEL: midori_view_set_zoom_level (view, g_value_get_float (value)); break; @@ -1705,6 +1750,9 @@ midori_view_get_property (GObject* object, case PROP_LOAD_STATUS: g_value_set_enum (value, midori_view_get_load_status (view)); break; + case PROP_MINIMIZED: + g_value_set_boolean (value, view->minimized); + break; case PROP_ZOOM_LEVEL: g_value_set_float (value, midori_view_get_zoom_level (view)); break; @@ -2455,6 +2503,13 @@ midori_view_tab_label_menu_duplicate_tab_cb (GtkWidget* menuitem, g_signal_emit (view, signals[NEW_VIEW], 0, new_view, where); } +static void +midori_view_tab_label_menu_minimize_tab_cb (GtkWidget* menuitem, + MidoriView* view) +{ + g_object_set (view, "minimized", !view->minimized, NULL); +} + static void midori_view_tab_label_menu_close_cb (GtkWidget* menuitem, GtkWidget* view) @@ -2494,6 +2549,11 @@ midori_view_get_tab_menu (MidoriView* view) gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); g_signal_connect (menuitem, "activate", G_CALLBACK (midori_view_tab_label_menu_duplicate_tab_cb), view); + menuitem = gtk_menu_item_new_with_mnemonic ( + view->minimized ? _("_Restore Tab") : _("_Minimize Tab")); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); + g_signal_connect (menuitem, "activate", + G_CALLBACK (midori_view_tab_label_menu_minimize_tab_cb), view); menuitem = gtk_separator_menu_item_new (); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLOSE, NULL); @@ -2763,6 +2823,16 @@ midori_view_get_proxy_tab_label (MidoriView* view) return view->tab_label; } +static void +midori_view_item_meta_data_changed (KatzeItem* item, + const gchar* key, + MidoriView* view) +{ + if (g_str_equal (key, "minimized")) + g_object_set (view, "minimized", + katze_item_get_meta_string (item, key) != NULL, NULL); +} + /** * midori_view_get_proxy_item: * @view: a #MidoriView @@ -2790,6 +2860,8 @@ midori_view_get_proxy_item (MidoriView* view) katze_item_set_uri (view->item, uri); title = midori_view_get_display_title (view); katze_item_set_name (view->item, title); + g_signal_connect (view->item, "meta-data-changed", + G_CALLBACK (midori_view_item_meta_data_changed), view); } return view->item; }