[epiphany-extensions/tabs-reloaded: 11/16] [tabs-reloaded] Use a custom cell renderer to render tabs
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [epiphany-extensions/tabs-reloaded: 11/16] [tabs-reloaded] Use a custom cell renderer to render tabs
- Date: Wed, 16 Dec 2009 16:51:24 +0000 (UTC)
commit d3b2b830b198d3156e6eeb7fd2890edac2c77f73
Author: Benjamin Otte <otte gnome org>
Date: Fri Aug 7 19:19:38 2009 +0200
[tabs-reloaded] Use a custom cell renderer to render tabs
extensions/tabs-reloaded/Makefile.am | 2 +
extensions/tabs-reloaded/ephy-cell-renderer-tab.c | 315 ++++++++++++++++++++
extensions/tabs-reloaded/ephy-cell-renderer-tab.h | 59 ++++
.../tabs-reloaded/ephy-tabs-reloaded-extension.c | 78 +-----
extensions/tabs-reloaded/tabs-reloaded.c | 2 +
extensions/tabs-reloaded/tabs-reloaded.ui | 24 +--
6 files changed, 386 insertions(+), 94 deletions(-)
---
diff --git a/extensions/tabs-reloaded/Makefile.am b/extensions/tabs-reloaded/Makefile.am
index f3e5160..29ecbde 100644
--- a/extensions/tabs-reloaded/Makefile.am
+++ b/extensions/tabs-reloaded/Makefile.am
@@ -2,6 +2,8 @@ extensiondir = $(EXTENSIONS_DIR)
extension_LTLIBRARIES = libtabsreloadedextension.la
libtabsreloadedextension_la_SOURCES = \
+ ephy-cell-renderer-tab.c \
+ ephy-cell-renderer-tab.h \
ephy-tabs-manager.c \
ephy-tabs-manager.h \
ephy-tabs-reloaded-extension.c \
diff --git a/extensions/tabs-reloaded/ephy-cell-renderer-tab.c b/extensions/tabs-reloaded/ephy-cell-renderer-tab.c
new file mode 100644
index 0000000..e869a57
--- /dev/null
+++ b/extensions/tabs-reloaded/ephy-cell-renderer-tab.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright © 2009 Benjamin Otte
+ *
+ * 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.
+ */
+
+
+#include "config.h"
+
+#include "ephy-cell-renderer-tab.h"
+
+enum {
+ PROP_0,
+ PROP_TAB,
+ PROP_COLUMNS
+};
+
+
+#define EPHY_CELL_RENDERER_TAB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EPHY_TYPE_CELL_RENDERER_TAB, EphyCellRendererTabPrivate))
+
+struct _EphyCellRendererTabPrivate
+{
+ EphyEmbed * tab; /* the tab we render */
+ guint n_columns; /* number of columns we occupy */
+};
+
+G_DEFINE_DYNAMIC_TYPE (EphyCellRendererTab, ephy_cell_renderer_tab, GTK_TYPE_CELL_RENDERER)
+
+void
+ephy_cell_renderer_tab_register (GTypeModule *module)
+{
+ ephy_cell_renderer_tab_register_type (module);
+}
+
+static guint
+ephy_cell_renderer_get_row_height (GtkWidget *widget)
+{
+ PangoFontMetrics *metrics;
+ guint height;
+
+ metrics = pango_context_get_metrics (gtk_widget_get_pango_context (widget),
+ widget->style->font_desc,
+ NULL);
+ height = PANGO_PIXELS (pango_font_metrics_get_ascent (metrics) +
+ pango_font_metrics_get_descent (metrics));
+
+ pango_font_metrics_unref (metrics);
+
+ return height;
+}
+
+static void
+ephy_cell_renderer_tab_get_size (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ GdkRectangle *cell_area,
+ gint *x_offset,
+ gint *y_offset,
+ gint *width,
+ gint *height)
+{
+ EphyCellRendererTab *renderer = EPHY_CELL_RENDERER_TAB (cell);
+ EphyCellRendererTabPrivate *priv = renderer->priv;
+
+ priv = EPHY_CELL_RENDERER_TAB_GET_PRIVATE (cell);
+
+ if (x_offset) *x_offset = 0;
+ if (y_offset) *y_offset = 0;
+
+ /*
+ * We don't request any width as the width is determined by the user.
+ * This way, we allow shrinking as much as the user wishes */
+ if (width)
+ *width = 2 * cell->xpad + 1;
+
+ if (height)
+ *height = 2 * cell->ypad + priv->n_columns * ephy_cell_renderer_get_row_height (widget);
+}
+
+static void
+ephy_cell_renderer_tab_render (GtkCellRenderer *cell,
+ GdkWindow *window,
+ GtkWidget *widget,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ GtkCellRendererState flags)
+
+{
+ EphyCellRendererTab *renderer = EPHY_CELL_RENDERER_TAB (cell);
+ EphyCellRendererTabPrivate *priv = renderer->priv;
+ EphyWebView *view;
+ WebKitWebView *webview;
+ GdkPixbuf *pixbuf;
+ cairo_t *cr;
+ guint x, y, width, height, row_height, n_columns;
+ int icon_width, icon_height;
+ PangoLayout *layout;
+
+ /* FIXME: render "add tab" button here */
+ if (priv->tab == NULL)
+ return;
+
+ view = ephy_embed_get_web_view (priv->tab);
+ webview = WEBKIT_WEB_VIEW (view);
+ row_height = ephy_cell_renderer_get_row_height (widget);
+ x = cell_area->x + cell->xpad;
+ y = cell_area->y + cell->ypad;
+ width = cell_area->width - 2 * cell->xpad;
+ height = cell_area->height - 2 * cell->ypad;
+ gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (widget),
+ GTK_ICON_SIZE_MENU,
+ &icon_width,
+ &icon_height);
+ n_columns = priv->n_columns;
+
+ /* setup cairo context:
+ * - clip to exposed area
+ * - set origin correctly
+ * - clip to cell area (minus padding)
+ */
+ cr = gdk_cairo_create (window);
+ gdk_cairo_rectangle (cr, expose_area);
+ cairo_clip (cr);
+ cairo_translate (cr, x, y);
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_clip (cr);
+
+ /* render the progressbar */
+ if (webkit_web_view_get_load_status (webview) != WEBKIT_LOAD_FINISHED)
+ {
+ GdkRectangle clip;
+ gtk_paint_box (widget->style,
+ window,
+ GTK_STATE_NORMAL, GTK_SHADOW_IN,
+ NULL, widget, NULL,
+ x, y + height - row_height, width, row_height);
+ clip.x = x;
+ clip.y = y + height - row_height;
+ clip.width = width * webkit_web_view_get_progress (webview) + 0.5;
+ clip.height = row_height;
+ gtk_paint_box (widget->style,
+ window,
+ GTK_STATE_SELECTED, GTK_SHADOW_OUT,
+ &clip, widget, "bar",
+ clip.x, clip.y,
+ clip.width, clip.height);
+ if (n_columns > 1)
+ n_columns--;
+ }
+
+ /* render the title */
+ layout = gtk_widget_create_pango_layout (widget,
+ ephy_web_view_get_title (view));
+ pango_layout_set_width (layout, width * PANGO_SCALE);
+ if (pango_layout_get_line_count (layout) >= n_columns)
+ {
+ if (ephy_web_view_get_icon (view))
+ pango_layout_set_indent (layout, icon_width * PANGO_SCALE);
+ }
+ pango_layout_set_height (layout, -(int)n_columns);
+ pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
+ gtk_paint_layout (widget->style,
+ window,
+ GTK_STATE_NORMAL, /* FIXME */
+ TRUE,
+ expose_area,
+ widget,
+ "cellrenderertext",
+ x,
+ y,
+ layout);
+ g_object_unref (layout);
+
+ /* render the icons */
+ cairo_translate (cr, cell_area->width, 0);
+ pixbuf = gtk_widget_render_icon (widget, "gtk-close", GTK_ICON_SIZE_MENU, NULL);
+ cairo_translate (cr, -icon_width, 0);
+ gdk_cairo_set_source_pixbuf (cr,
+ pixbuf,
+ (icon_width - gdk_pixbuf_get_width (pixbuf)) / 2,
+ (icon_height - gdk_pixbuf_get_height (pixbuf)) / 2);
+ cairo_paint_with_alpha (cr, flags & GTK_CELL_RENDERER_PRELIT ? 1.0 : 0.3);
+ g_object_unref (pixbuf);
+
+ cairo_destroy (cr);
+}
+
+static void
+ephy_cell_renderer_tab_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EphyCellRendererTab *renderer = EPHY_CELL_RENDERER_TAB (object);
+ EphyCellRendererTabPrivate *priv = renderer->priv;
+
+ switch (param_id)
+ {
+ case PROP_TAB:
+ g_value_set_object (value, priv->tab);
+ break;
+ case PROP_COLUMNS:
+ g_value_set_uint (value, priv->n_columns);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+ephy_cell_renderer_tab_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EphyCellRendererTab *renderer = EPHY_CELL_RENDERER_TAB (object);
+ EphyCellRendererTabPrivate *priv = renderer->priv;
+
+ switch (param_id)
+ {
+ case PROP_TAB:
+ if (priv->tab)
+ g_object_unref (priv->tab);
+ priv->tab = g_value_dup_object (value);
+ break;
+ case PROP_COLUMNS:
+ priv->n_columns = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+ephy_cell_renderer_tab_finalize (GObject *object)
+{
+ EphyCellRendererTab *renderer = EPHY_CELL_RENDERER_TAB (object);
+ EphyCellRendererTabPrivate *priv = renderer->priv;
+
+ if (priv->tab)
+ g_object_unref (priv->tab);
+
+ G_OBJECT_CLASS (ephy_cell_renderer_tab_parent_class)->finalize (object);
+}
+
+static void
+ephy_cell_renderer_tab_class_finalize (EphyCellRendererTabClass *class)
+{
+}
+
+static void
+ephy_cell_renderer_tab_class_init (EphyCellRendererTabClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
+
+ object_class->finalize = ephy_cell_renderer_tab_finalize;
+
+ object_class->get_property = ephy_cell_renderer_tab_get_property;
+ object_class->set_property = ephy_cell_renderer_tab_set_property;
+
+ cell_class->get_size = ephy_cell_renderer_tab_get_size;
+ cell_class->render = ephy_cell_renderer_tab_render;
+
+ g_object_class_install_property (object_class,
+ PROP_TAB,
+ g_param_spec_object ("tab",
+ "tab",
+ "the tab to render",
+ EPHY_TYPE_EMBED,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_COLUMNS,
+ g_param_spec_uint ("columns",
+ "columns",
+ "number of text columns to span",
+ 1,
+ G_MAXUINT,
+ 1,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (object_class, sizeof (EphyCellRendererTabPrivate));
+}
+
+static void
+ephy_cell_renderer_tab_init (EphyCellRendererTab *renderer)
+{
+ EphyCellRendererTabPrivate *priv;
+
+ priv = renderer->priv = EPHY_CELL_RENDERER_TAB_GET_PRIVATE (renderer);
+
+ priv->n_columns = 1;
+}
+
+GtkCellRenderer *
+ephy_cell_renderer_tab_new (void)
+{
+ return g_object_new (EPHY_TYPE_CELL_RENDERER_TAB, NULL);
+}
+
diff --git a/extensions/tabs-reloaded/ephy-cell-renderer-tab.h b/extensions/tabs-reloaded/ephy-cell-renderer-tab.h
new file mode 100644
index 0000000..5250306
--- /dev/null
+++ b/extensions/tabs-reloaded/ephy-cell-renderer-tab.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2009 Benjamin Otte
+ *
+ * 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 EPHY_CELL_RENDERER_TAB_H
+
+#include <epiphany/epiphany.h>
+
+
+G_BEGIN_DECLS
+
+
+#define EPHY_TYPE_CELL_RENDERER_TAB (ephy_cell_renderer_tab_get_type ())
+#define EPHY_CELL_RENDERER_TAB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_CELL_RENDERER_TAB, EphyCellRendererTab))
+#define EPHY_CELL_RENDERER_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_CELL_RENDERER_TAB, EphyCellRendererTabClass))
+#define EPHY_IS_CELL_RENDERER_TAB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_CELL_RENDERER_TAB))
+#define EPHY_IS_CELL_RENDERER_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EPHY_TYPE_CELL_RENDERER_TAB))
+#define EPHY_CELL_RENDERER_TAB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EPHY_TYPE_CELL_RENDERER_TAB, EphyCellRendererTabClass))
+
+typedef struct _EphyCellRendererTab EphyCellRendererTab;
+typedef struct _EphyCellRendererTabClass EphyCellRendererTabClass;
+typedef struct _EphyCellRendererTabPrivate EphyCellRendererTabPrivate;
+
+struct _EphyCellRendererTab
+{
+ GtkCellRenderer parent;
+
+ EphyCellRendererTabPrivate *priv;
+};
+
+struct _EphyCellRendererTabClass
+{
+ GtkCellRendererClass parent_class;
+};
+
+GType ephy_cell_renderer_tab_get_type (void) G_GNUC_CONST;
+void ephy_cell_renderer_tab_register (GTypeModule *module);
+
+GtkCellRenderer *ephy_cell_renderer_tab_new (void);
+
+
+G_END_DECLS
+
+
+#endif /* EPHY_CELL_RENDERER_TAB_H */
diff --git a/extensions/tabs-reloaded/ephy-tabs-reloaded-extension.c b/extensions/tabs-reloaded/ephy-tabs-reloaded-extension.c
index 90ab339..f774c8c 100644
--- a/extensions/tabs-reloaded/ephy-tabs-reloaded-extension.c
+++ b/extensions/tabs-reloaded/ephy-tabs-reloaded-extension.c
@@ -79,81 +79,12 @@ ephy_tabs_reloaded_extension_register_type (GTypeModule *module)
}
static void
-pixbuf_renderer_cell_data_func (GtkCellLayout * column,
- GtkCellRenderer *renderer,
- GtkTreeModel * model,
- GtkTreeIter * iter,
- gpointer unused)
-{
- EphyEmbed *embed;
- EphyWebView *view;
-
- embed = ephy_tabs_manager_get_tab (EPHY_TABS_MANAGER (model),
- iter);
- view = ephy_embed_get_web_view (embed);
-
- g_object_set (renderer,
- "pixbuf", ephy_web_view_get_icon (view),
- "visible", ephy_web_view_get_icon (view) != NULL,
- NULL);
-}
-
-static void
-text_renderer_cell_data_func (GtkCellLayout * column,
- GtkCellRenderer *renderer,
- GtkTreeModel * model,
- GtkTreeIter * iter,
- gpointer unused)
-{
- EphyEmbed *embed;
- EphyWebView *view;
- WebKitWebView *webkit;
-
- embed = ephy_tabs_manager_get_tab (EPHY_TABS_MANAGER (model),
- iter);
- view = ephy_embed_get_web_view (embed);
- webkit = WEBKIT_WEB_VIEW (view);
-
- g_object_set (renderer,
- "text", ephy_web_view_get_title (view),
- "visible", webkit_web_view_get_load_status (webkit) == WEBKIT_LOAD_FINISHED,
- NULL);
-}
-
-static void
-progress_renderer_cell_data_func (GtkCellLayout * column,
- GtkCellRenderer *renderer,
- GtkTreeModel * model,
- GtkTreeIter * iter,
- gpointer unused)
-{
- EphyEmbed *embed;
- EphyWebView *view;
- WebKitWebView *webkit;
-
- embed = ephy_tabs_manager_get_tab (EPHY_TABS_MANAGER (model),
- iter);
- view = ephy_embed_get_web_view (embed);
- webkit = WEBKIT_WEB_VIEW (view);
-
- g_object_set (renderer,
- "text", ephy_web_view_get_title (view),
- "value", (int) (webkit_web_view_get_progress (webkit) * 100. + 0.5),
- "visible", webkit_web_view_get_load_status (webkit) != WEBKIT_LOAD_FINISHED,
- NULL);
-}
-
-static void
sanitize_tree_view (GtkTreeView *view)
{
static const struct {
- GtkCellLayoutDataFunc func;
gboolean expand;
} cell_info[] = {
- { pixbuf_renderer_cell_data_func, FALSE },
- { text_renderer_cell_data_func, TRUE },
- { progress_renderer_cell_data_func, TRUE },
- { NULL /* close button */, FALSE }
+ { TRUE }
};
GtkCellLayout *column;
GtkCellRenderer *renderer;
@@ -173,13 +104,8 @@ sanitize_tree_view (GtkTreeView *view)
{
renderer = walk->data;
gtk_cell_layout_pack_start (column, renderer, cell_info[renderer_id].expand);
- if (cell_info[renderer_id].func)
- gtk_cell_layout_set_cell_data_func (column,
- renderer,
- cell_info[renderer_id].func,
- NULL,
- NULL);
renderer_id++;
+ gtk_cell_layout_set_attributes (column, renderer, "tab", 0, NULL);
}
g_list_foreach (renderers, (GFunc) g_object_unref, NULL);
g_list_free (renderers);
diff --git a/extensions/tabs-reloaded/tabs-reloaded.c b/extensions/tabs-reloaded/tabs-reloaded.c
index 2c56acc..eb81c7d 100644
--- a/extensions/tabs-reloaded/tabs-reloaded.c
+++ b/extensions/tabs-reloaded/tabs-reloaded.c
@@ -18,6 +18,7 @@
#include "config.h"
+#include "ephy-cell-renderer-tab.h"
#include "ephy-tabs-manager.h"
#include "ephy-tabs-reloaded-extension.h"
@@ -34,6 +35,7 @@ register_module (GTypeModule *module)
extension_type = ephy_tabs_reloaded_extension_register_type (module);
ephy_tabs_manager_register (module);
+ ephy_cell_renderer_tab_register (module);
#ifdef ENABLE_NLS
/* Initialise i18n */
diff --git a/extensions/tabs-reloaded/tabs-reloaded.ui b/extensions/tabs-reloaded/tabs-reloaded.ui
index f7c5d09..30b0166 100644
--- a/extensions/tabs-reloaded/tabs-reloaded.ui
+++ b/extensions/tabs-reloaded/tabs-reloaded.ui
@@ -19,6 +19,7 @@
<property name="can_focus">True</property>
<property name="headers_visible">False</property>
<property name="headers_clickable">False</property>
+ <property name="rules-hint">True</property>
<property name="search_column">0</property>
<property name="show_expanders">False</property>
<child>
@@ -26,25 +27,12 @@
<property name="title">column</property>
<property name="expand">True</property>
<child>
- <object class="GtkCellRendererPixbuf" id="icon"/>
- </child>
- <child>
- <object class="GtkCellRendererText" id="title">
- <property name="width">1</property>
- <property name="ellipsize">end</property>
- <property name="single_paragraph_mode">True</property>
- </object>
- </child>
- <child>
- <object class="GtkCellRendererProgress" id="progress">
- <property name="width">1</property>
- <property name="text_xalign">0</property>
- </object>
- </child>
- <child>
- <object class="GtkCellRendererPixbuf" id="close">
- <property name="stock_id">gtk-close</property>
+ <object class="EphyCellRendererTab" id="icon">
+ <property name="columns">4</property>
</object>
+ <attributes>
+ <attribute name="tab">0</attribute>
+ </attributes>
</child>
</object>
</child>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]