Hidetaka Iwai
tyuyu****@sings*****
2004年 12月 5日 (日) 01:32:13 JST
岩井@札幌です。 サムネイル付きタブリストを試験的に実装してみました。見栄えは良くありま せんが、とりあえず "ThumbnailTabList" action でタブリストが出ます。 現在の問題点としては 1. タブの数が多い時にサムネイルがスマートに配置されない。 KzThumbnailView を hack して KZ_THUMBNAILS_VIEW_SMART とか作る必要 あり? 2. キーイベントを拾ってない 3. サムネイル上にマウスをかざしたときに、ページのタイトルや URI をツー ルチップか何かで表示したほうが良い です。パッチを添付します。 regards, -- Hidetaka Iwai tyuyu****@sings***** -------------- next part -------------- Index: src/Makefile.am =================================================================== RCS file: /cvsroot/kazehakase/kazehakase/src/Makefile.am,v retrieving revision 1.101 diff -u -r1.101 Makefile.am --- src/Makefile.am 2 Dec 2004 15:53:28 -0000 1.101 +++ src/Makefile.am 4 Dec 2004 16:19:09 -0000 @@ -58,7 +58,8 @@ kz-langinfo.c kz-langinfo.h \ kz-thumbnails-view.c kz-thumbnails-view.h \ kz-autoscroller.c kz-autoscroller.h \ - kz-popup-preview.c kz-popup-preview.h + kz-popup-preview.c kz-popup-preview.h \ + kz-popup-tablist.c kz-popup-tablist.h nodist_kz_SOURCES = kz-marshalers.c kz-marshalers.h Index: src/kz-popup-tablist.c =================================================================== RCS file: src/kz-popup-tablist.c diff -N src/kz-popup-tablist.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/kz-popup-tablist.c 4 Dec 2004 16:19:09 -0000 @@ -0,0 +1,208 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2004 Hidetaka Iwai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#include "kazehakase.h" +#include "kz-popup-tablist.h" +#include "kz-thumbnails-view.h" +#include "kz-bookmark.h" +#include "kz-embed.h" +#include "gobject-utils.h" +#include "glib-utils.h" +#include "utils.h" + +typedef struct _KzPopupTablistPriv KzPopupTablistPriv; +struct _KzPopupTablistPriv +{ + GtkWidget *popup_window; + GtkWidget *popup_frame; + GtkWidget *view; + + gboolean now_shown; +}; + +#define KZ_POPUP_TABLIST_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), KZ_TYPE_POPUP_TABLIST, KzPopupTablistPriv)) + +enum { + SELECTED_SIGNAL, + LAST_SIGNAL +}; + +static void kz_popup_tablist_class_init (KzPopupTablistClass *klass); +static void kz_popup_tablist_init (KzPopupTablist *popup); +static void kz_popup_tablist_dispose (GObject *object); + +static void cb_thumbnail_activate (KzThumbnailsView *view, + KzBookmark *bookmark, + KzPopupTablist *popup); + +static GObjectClass *parent_class = NULL; +static KzPopupTablist *kz_popup_tablist_single = NULL; + +static gint kz_popup_tablist_signals[LAST_SIGNAL] = {0}; + +KZ_OBJECT_GET_TYPE(kz_popup_tablist, "KzPopupTablist", KzPopupTablist, + kz_popup_tablist_class_init, kz_popup_tablist_init, + G_TYPE_OBJECT) + +static void +kz_popup_tablist_class_init (KzPopupTablistClass *klass) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (klass); + object_class = (GObjectClass *) klass; + + object_class->dispose = kz_popup_tablist_dispose; + + + kz_popup_tablist_signals[SELECTED_SIGNAL] + = g_signal_new ("selected", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + G_STRUCT_OFFSET (KzPopupTablistClass, selected), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, KZ_TYPE_BOOKMARK); + + + g_type_class_add_private (klass, sizeof(KzPopupTablistPriv)); +} + +static void +kz_popup_tablist_init (KzPopupTablist *popup) +{ + KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE (popup); + GtkWidget *frame; + + priv->popup_window = gtk_window_new(GTK_WINDOW_POPUP); + + frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(frame, GTK_SHADOW_ETCHED_IN); + gtk_widget_show(frame); + priv->popup_frame = frame; + gtk_container_add(GTK_CONTAINER(priv->popup_window), frame); + + priv->view = NULL; + priv->now_shown = FALSE; +} + +static void +kz_popup_tablist_dispose (GObject *object) +{ + KzPopupTablist *popup = KZ_POPUP_TABLIST (object); + KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE (popup); + + if (priv->view) + { + gtk_container_remove(GTK_CONTAINER(priv->popup_frame), + priv->view); + priv->view = NULL; + } + + if (priv->popup_frame) + { + gtk_container_remove(GTK_CONTAINER(priv->popup_window), + priv->popup_frame); + } + + if (priv->popup_window != NULL) + { + gtk_widget_destroy(priv->popup_window); + priv->popup_window = NULL; + } + + if (G_OBJECT_CLASS (parent_class)->dispose) + G_OBJECT_CLASS (parent_class)->dispose(object); +} + +KzPopupTablist * +kz_popup_tablist_new (void) +{ + KzPopupTablist* popup = g_object_new (KZ_TYPE_POPUP_TABLIST, NULL); + + return popup; +} + +KzPopupTablist * +kz_popup_tablist_get_instance (void) +{ + if (!kz_popup_tablist_single) + kz_popup_tablist_single = kz_popup_tablist_new(); + else + g_object_ref(kz_popup_tablist_single); + + return kz_popup_tablist_single; +} + +void +kz_popup_tablist_show(KzPopupTablist *popup, KzBookmark* tabs) +{ + KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE (popup); + GtkWidget *view; + + if(priv->now_shown) + return; + view = kz_thumbnails_view_new(); + + kz_thumbnails_view_set_mode(KZ_THUMBNAILS_VIEW(view), KZ_THUMBNAILS_VIEW_HORIZONTAL); + gtk_widget_show(view); + + if(priv->view) + { + gtk_container_remove(GTK_CONTAINER(priv->popup_frame), + priv->view); + } + priv->view = view; + + gtk_container_add(GTK_CONTAINER(priv->popup_frame), view); + kz_thumbnails_view_set_folder(KZ_THUMBNAILS_VIEW(view), + tabs); + + g_signal_connect(G_OBJECT(view), + "activate", + G_CALLBACK(cb_thumbnail_activate), + popup); + + priv->now_shown = TRUE; + gtk_window_set_position (GTK_WINDOW (priv->popup_window), GTK_WIN_POS_CENTER); + gtk_widget_show_all(priv->popup_window); +} + +void +kz_popup_tablist_hide(KzPopupTablist *popup) +{ + KzPopupTablistPriv *priv = KZ_POPUP_TABLIST_GET_PRIVATE (popup); + gtk_widget_hide_all(priv->popup_window); + priv->now_shown = FALSE; +} + +static void +cb_thumbnail_activate (KzThumbnailsView *view, KzBookmark *tab, + KzPopupTablist *popup) +{ + g_signal_emit(G_OBJECT(popup), + kz_popup_tablist_signals[SELECTED_SIGNAL], 0, tab); +} Index: src/kz-popup-tablist.h =================================================================== RCS file: src/kz-popup-tablist.h diff -N src/kz-popup-tablist.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/kz-popup-tablist.h 4 Dec 2004 16:19:10 -0000 @@ -0,0 +1,60 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ + +/* + * Copyright (C) 2004 Hidetaka Iwai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __KZ_POPUP_TABLIST_H__ +#define __KZ_POPUP_TABLIST_H__ + + +#include <gtk/gtk.h> +#include "kz-bookmark.h" + +G_BEGIN_DECLS + +#define KZ_TYPE_POPUP_TABLIST (kz_popup_tablist_get_type ()) +#define KZ_POPUP_TABLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KZ_TYPE_POPUP_TABLIST, KzPopupTablist)) +#define KZ_POPUP_TABLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KZ_TYPE_POPUP_TABLIST, KzPopupTablistClass)) +#define KZ_IS_POPUP_TABLIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KZ_TYPE_POPUP_TABLIST)) +#define KZ_IS_POPUP_TABLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KZ_TYPE_POPUP_TABLIST)) +#define KZ_POPUP_TABLIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KZ_TYPE_POPUP_TABLIST, KzPopupTablistClass)) + +typedef struct _KzPopupTablistClass KzPopupTablistClass; +typedef struct _KzPopupTablist KzPopupTablist; + +struct _KzPopupTablist +{ + GObject parent; +}; + +struct _KzPopupTablistClass +{ + GObjectClass parent_class; + void (*selected) (KzPopupTablist* popup); +}; + +GType kz_popup_tablist_get_type (void) G_GNUC_CONST; +KzPopupTablist* kz_popup_tablist_new (void); +KzPopupTablist* kz_popup_tablist_get_instance (void); + +void kz_popup_tablist_show (KzPopupTablist *popup, KzBookmark *tabs); +void kz_popup_tablist_hide (KzPopupTablist *popup); + +G_END_DECLS + +#endif /* __KZ_POPUP_TABLIST_H__ */ Index: src/kz-window.c =================================================================== RCS file: /cvsroot/kazehakase/kazehakase/src/kz-window.c,v retrieving revision 1.206 diff -u -r1.206 kz-window.c --- src/kz-window.c 3 Dec 2004 15:56:56 -0000 1.206 +++ src/kz-window.c 4 Dec 2004 16:19:11 -0000 @@ -415,6 +415,7 @@ kz->kzfav = kz_favicon_get_instance(); kz->popup = kz_popup_preview_get_instance(); + kz->tablist = kz_popup_tablist_get_instance(); kz->priv = g_new0(KzWindowPriv, 1); kz->priv->merge_id = 0; @@ -1515,7 +1516,9 @@ if (kz->popup) g_object_unref(kz->popup); kz->popup = NULL; - + if (kz->tablist) + g_object_unref(kz->tablist); + kz->tablist = NULL; if (kz->tabs) { Index: src/kz-window.h =================================================================== RCS file: /cvsroot/kazehakase/kazehakase/src/kz-window.h,v retrieving revision 1.56 diff -u -r1.56 kz-window.h --- src/kz-window.h 2 Dec 2004 15:53:28 -0000 1.56 +++ src/kz-window.h 4 Dec 2004 16:19:11 -0000 @@ -29,6 +29,7 @@ #include "kz-embed.h" #include "kz-favicon.h" #include "kz-popup-preview.h" +#include "kz-popup-tablist.h" #include "kz-bookmark.h" G_BEGIN_DECLS @@ -81,6 +82,7 @@ /* handle for favicon */ KzFavicon *kzfav; KzPopupPreview *popup; + KzPopupTablist *tablist; gboolean is_closing_all; Index: src/actions/kz-actions.c =================================================================== RCS file: /cvsroot/kazehakase/kazehakase/src/actions/kz-actions.c,v retrieving revision 1.170 diff -u -r1.170 kz-actions.c --- src/actions/kz-actions.c 26 Nov 2004 03:45:12 -0000 1.170 +++ src/actions/kz-actions.c 4 Dec 2004 16:19:13 -0000 @@ -34,6 +34,7 @@ #include "kz-links-dialog.h" #include "kz-password-manager-dialog.h" #include "kz-smart-bookmark.h" +#include "kz-bookmark.h" #include "kz-bookmark-editor.h" #include "kz-bookmark-edit-win.h" #include "kz-bookmark-filter.h" @@ -50,11 +51,14 @@ #include "kz-paned.h" #include "kz-bookmark-menu.h" #include "kz-autoscroller.h" +#include "kz-popup-tablist.h" #include "eggregex.h" #include <time.h> #define HTTP_REGEX "(https?://[-_.!~*'()a-zA-Z0-9;/?:@&=+$,%#]+)" +#define KZ_ACTIONS_TABLIST_KEY "KzActions::Tablist" + enum { UI_BEGINNER, UI_MEDIUM, @@ -1654,6 +1658,66 @@ g_object_unref (as); } +static KzBookmark * +create_proxy_folder (KzWindow* kz) +{ + gint i; + const gint num = gtk_notebook_get_n_pages(GTK_NOTEBOOK(kz->notebook)); + KzBookmark *ret_bookmark; + + ret_bookmark = kz_bookmark_pure_folder_new(); + + for (i = 0; i < num; i++) + { + KzEmbed *kzembed = KZ_EMBED(KZ_WINDOW_NTH_PAGE(kz, i)); + + if (KZ_EMBED(kzembed)) + { + KzBookmark *tab; + const gchar *title = kz_embed_ensure_title(kzembed); + const gchar *link = kz_embed_get_location(kzembed); + + tab = kz_bookmark_new_with_attrs(title, link, NULL); + + g_object_set_data (G_OBJECT(tab), KZ_ACTIONS_TABLIST_KEY, kzembed); + + kz_bookmark_append(ret_bookmark, tab); + g_object_unref(tab); + } + } + return ret_bookmark; +} + + +static void +cb_thumbnail_tablist_selected (KzPopupTablist *popup, KzBookmark* tab, KzWindow* kz) +{ + GtkWidget *kzembed; + gint page_num; + + kzembed = g_object_get_data (G_OBJECT(tab), KZ_ACTIONS_TABLIST_KEY); + + page_num = gtk_notebook_page_num(GTK_NOTEBOOK(kz->notebook), + GTK_WIDGET(kzembed)); + + gtk_notebook_set_current_page(GTK_NOTEBOOK(kz->notebook), page_num); + + kz_popup_tablist_hide(popup); +} + +static void +act_thumbnail_tablist (GtkAction *action, KzWindow *kz) +{ + KzBookmark *proxy; + KzPopupTablist *popup = kz_popup_tablist_get_instance(); + + proxy = create_proxy_folder(kz); + g_signal_connect(G_OBJECT(popup), "selected", + G_CALLBACK(cb_thumbnail_tablist_selected), kz); +/* to keep KzPopupTablist from adhering to KzWindow, I can't pass KzWindow to KzPopupTablist directly... */ + kz_popup_tablist_show(popup, proxy); +} + /* toggle actios */ static void act_show_hide_sidebar (GtkAction *action, KzWindow *kz) @@ -1769,6 +1833,7 @@ {"ViewPageSource", KZ_STOCK_VIEW_SOURCE, N_("View page source"), NULL, N_("View the source code of the page"), G_CALLBACK(act_view_source)}, {"AutoScrollMode", NULL, N_("Autoscroll mode"), NULL, N_("set auto-scroll mode"), G_CALLBACK(act_auto_scroll_mode)}, + {"ThumbnailTabList", NULL, N_("ThumbnailTabList"), NULL, N_("Display the tab list with thumbnail"), G_CALLBACK(act_thumbnail_tablist)}, /* {"EditMode", KZ_STOCK_VIEW_SOURCE, N_("EditMode"), NULL, N_("View the source code of the page"), G_CALLBACK(act_set_edit_mode)}, {"ViewMode", KZ_STOCK_VIEW_SOURCE, N_("EditMode"), NULL, N_("View the source code of the page"), G_CALLBACK(act_set_view_mode)},