[gnome-keyring] Calculate the minimal/natural size of certificate widget better.



commit 57fec1af8b412bc8ce6822d7d1b7d7f413fe7c5f
Author: Stef Walter <stefw collabora co uk>
Date:   Fri Mar 4 18:43:29 2011 +0100

    Calculate the minimal/natural size of certificate widget  better.
    
     * These are still just gueseses. But they're guesses that look good.
     * Added a new GcrViewer implementation that is a scrolled viewer.
       We use this in GcrCertificateWidget instead of using GtkScrolledWindow
       directly.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=643892

 gcr/Makefile.am                 |    1 +
 gcr/gcr-certificate-widget.c    |   13 +---
 gcr/gcr-display-scrolled.c      |  172 +++++++++++++++++++++++++++++++++++++++
 gcr/gcr-display-scrolled.h      |   56 +++++++++++++
 gcr/gcr-display-view.c          |  105 ++++++++++++++++++++++++
 gcr/gcr-viewer.c                |    7 ++
 gcr/gcr-viewer.h                |    2 +
 gcr/tests/ui-test-certificate.c |    1 -
 8 files changed, 346 insertions(+), 11 deletions(-)
---
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index 264ac8a..2201f85 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -67,6 +67,7 @@ libgcr GCR_VERSION_SUFFIX@_la_SOURCES = \
 	gcr-certificate-chain.c gcr-certificate-chain.h \
 	gcr-certificate-renderer.c gcr-certificate-renderer.h \
 	gcr-certificate-widget.c gcr-certificate-widget.h \
+	gcr-display-scrolled.c gcr-display-scrolled.h \
 	gcr-display-view.c gcr-display-view.h \
 	gcr-icons.c gcr-icons.h \
 	gcr-import-dialog.c gcr-import-dialog.h \
diff --git a/gcr/gcr-certificate-widget.c b/gcr/gcr-certificate-widget.c
index 8e61063..7bb4b8a 100644
--- a/gcr/gcr-certificate-widget.c
+++ b/gcr/gcr-certificate-widget.c
@@ -52,21 +52,14 @@ gcr_certificate_widget_constructor (GType type, guint n_props, GObjectConstructP
 {
 	GObject *obj = G_OBJECT_CLASS (gcr_certificate_widget_parent_class)->constructor (type, n_props, props);
 	GcrCertificateWidget *self = NULL;
-	GtkWidget *scroll;
 
 	g_return_val_if_fail (obj, NULL);
 
 	self = GCR_CERTIFICATE_WIDGET (obj);
 
-	self->pv->viewer = gcr_viewer_new ();
-
-	scroll = gtk_scrolled_window_new (NULL, NULL);
-	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_ETCHED_IN);
-	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-	gtk_container_add (GTK_CONTAINER (scroll), GTK_WIDGET (self->pv->viewer));
-
-	gtk_container_add (GTK_CONTAINER (self), scroll);
-	gtk_widget_show_all (scroll);
+	self->pv->viewer = gcr_viewer_new_scrolled ();
+	gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->pv->viewer));
+	gtk_widget_show (GTK_WIDGET (self->pv->viewer));
 
 	gcr_viewer_add_renderer (self->pv->viewer, GCR_RENDERER (self->pv->renderer));
 	return obj;
diff --git a/gcr/gcr-display-scrolled.c b/gcr/gcr-display-scrolled.c
new file mode 100644
index 0000000..222c7af
--- /dev/null
+++ b/gcr/gcr-display-scrolled.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program 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.1 of
+ * the License, 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+
+#include "config.h"
+
+#include "gcr-display-scrolled.h"
+#include "gcr-viewer.h"
+
+static void _gcr_display_scrolled_viewer_iface (GcrViewerIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcrDisplayScrolled, _gcr_display_scrolled, GTK_TYPE_SCROLLED_WINDOW,
+                         G_IMPLEMENT_INTERFACE (GCR_TYPE_VIEWER, _gcr_display_scrolled_viewer_iface));
+
+struct _GcrDisplayScrolledPrivate {
+	GcrViewer *internal;
+};
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static void
+_gcr_display_scrolled_init (GcrDisplayScrolled *self)
+{
+	self->pv = (G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_DISPLAY_SCROLLED, GcrDisplayScrolledPrivate));
+	self->pv->internal = gcr_viewer_new ();
+}
+
+static void
+_gcr_display_scrolled_constructed (GObject *object)
+{
+	GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (object);
+
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self), GTK_SHADOW_ETCHED_IN);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+	gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->pv->internal));
+	gtk_widget_show (GTK_WIDGET (self->pv->internal));
+}
+
+#if GTK_CHECK_VERSION (3,0,0)
+
+static void
+_gcr_display_scrolled_get_preferred_height (GtkWidget *widget, gint *minimal_height,
+                                            gint *natural_height)
+{
+	GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (widget);
+	gint minimal, natural;
+
+	GTK_WIDGET_CLASS (_gcr_display_scrolled_parent_class)->get_preferred_height (widget,
+	                                                                             minimal_height,
+	                                                                             natural_height);
+
+	minimal = 0;
+	natural = 0;
+
+	gtk_widget_get_preferred_height (GTK_WIDGET (self->pv->internal),
+	                                 &minimal, &natural);
+
+	/* This is messy, we add a extra for the etching height */
+	*minimal_height = MAX (minimal + 3, *minimal_height);
+	*natural_height = MAX (natural + 3, *natural_height);
+}
+
+static void
+_gcr_display_scrolled_get_preferred_width (GtkWidget *widget, gint *minimal_width,
+                                           gint *natural_width)
+{
+	GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (widget);
+	gint minimal, natural;
+
+	GTK_WIDGET_CLASS (_gcr_display_scrolled_parent_class)->get_preferred_width (widget,
+	                                                                            minimal_width,
+	                                                                            natural_width);
+
+	minimal = 0;
+	natural = 0;
+
+	gtk_widget_get_preferred_width (GTK_WIDGET (self->pv->internal),
+	                                &minimal, &natural);
+
+	/* This is messy, we add a extra for the scrollbar width, etching */
+	*minimal_width = MAX (minimal + 32, *minimal_width);
+	*natural_width = MAX (natural + 32, *natural_width);
+}
+
+#endif /* GTK 3.x */
+
+static void
+_gcr_display_scrolled_class_init (GcrDisplayScrolledClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+#if GTK_CHECK_VERSION (3,0,0)
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+	widget_class->get_preferred_height = _gcr_display_scrolled_get_preferred_height;
+	widget_class->get_preferred_width = _gcr_display_scrolled_get_preferred_width;
+#endif
+
+	object_class->constructed = _gcr_display_scrolled_constructed;
+
+	g_type_class_add_private (klass, sizeof (GcrDisplayScrolledPrivate));
+}
+
+static void
+_gcr_display_scrolled_real_add_renderer (GcrViewer *viewer, GcrRenderer *renderer)
+{
+	GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
+	gcr_viewer_add_renderer (self->pv->internal, renderer);
+}
+
+static void
+_gcr_display_scrolled_real_remove_renderer (GcrViewer *viewer, GcrRenderer *renderer)
+{
+	GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
+	gcr_viewer_remove_renderer (self->pv->internal, renderer);
+}
+
+static guint
+_gcr_display_scrolled_real_count_renderers (GcrViewer *viewer)
+{
+	GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
+	return gcr_viewer_count_renderers (self->pv->internal);
+}
+
+static GcrRenderer*
+_gcr_display_scrolled_real_get_renderer (GcrViewer *viewer, guint index_)
+{
+	GcrDisplayScrolled *self = GCR_DISPLAY_SCROLLED (viewer);
+	return gcr_viewer_get_renderer (self->pv->internal, index_);
+}
+
+static void
+_gcr_display_scrolled_viewer_iface (GcrViewerIface *iface)
+{
+	iface->add_renderer = _gcr_display_scrolled_real_add_renderer;
+	iface->remove_renderer = _gcr_display_scrolled_real_remove_renderer;
+	iface->count_renderers = _gcr_display_scrolled_real_count_renderers;
+	iface->get_renderer = _gcr_display_scrolled_real_get_renderer;
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrDisplayScrolled*
+_gcr_display_scrolled_new (void)
+{
+	return g_object_new (GCR_TYPE_DISPLAY_SCROLLED, NULL);
+}
diff --git a/gcr/gcr-display-scrolled.h b/gcr/gcr-display-scrolled.h
new file mode 100644
index 0000000..f4ca02b
--- /dev/null
+++ b/gcr/gcr-display-scrolled.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program 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.1 of
+ * the License, 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#ifndef __GCR_DISPLAY_SCROLLED_H__
+#define __GCR_DISPLAY_SCROLLED_H__
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GCR_TYPE_DISPLAY_SCROLLED               (_gcr_display_scrolled_get_type ())
+#define GCR_DISPLAY_SCROLLED(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_DISPLAY_SCROLLED, GcrDisplayScrolled))
+#define GCR_DISPLAY_SCROLLED_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_DISPLAY_SCROLLED, GcrDisplayScrolledClass))
+#define GCR_IS_DISPLAY_SCROLLED(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_DISPLAY_SCROLLED))
+#define GCR_IS_DISPLAY_SCROLLED_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_DISPLAY_SCROLLED))
+#define GCR_DISPLAY_SCROLLED_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_DISPLAY_SCROLLED, GcrDisplayScrolledClass))
+
+typedef struct _GcrDisplayScrolled GcrDisplayScrolled;
+typedef struct _GcrDisplayScrolledClass GcrDisplayScrolledClass;
+typedef struct _GcrDisplayScrolledPrivate GcrDisplayScrolledPrivate;
+
+struct _GcrDisplayScrolled {
+	GtkScrolledWindow parent;
+	GcrDisplayScrolledPrivate *pv;
+};
+
+struct _GcrDisplayScrolledClass {
+	GtkScrolledWindowClass parent_class;
+};
+
+GType                _gcr_display_scrolled_get_type                    (void);
+
+GcrDisplayScrolled*  _gcr_display_scrolled_new                         (void);
+
+G_END_DECLS
+
+#endif /* __GCR_DISPLAY_SCROLLED_H__ */
diff --git a/gcr/gcr-display-view.c b/gcr/gcr-display-view.c
index 4a620e1..cac086d 100644
--- a/gcr/gcr-display-view.c
+++ b/gcr/gcr-display-view.c
@@ -62,12 +62,87 @@ struct _GcrDisplayViewPrivate {
 	GtkTextTag *content_tag;
 	GtkTextTag *heading_tag;
 	GtkTextTag *monospace_tag;
+
+	gboolean have_measurements;
+	gint minimal_width;
+	gint natural_width;
+	gint minimal_height;
+	gint natural_height;
 };
 
 /* -----------------------------------------------------------------------------
  * INTERNAL
  */
 
+#if GTK_CHECK_VERSION (3,0,0)
+
+static void
+ensure_measurements (GcrDisplayView *self)
+{
+	PangoLayout *layout;
+	PangoRectangle extents;
+	gint icon_width;
+	gint icon_height;
+	GHashTableIter iter;
+	GcrDisplayItem *item;
+	gpointer value;
+	gboolean expanded;
+
+	if (self->pv->have_measurements)
+		return;
+
+	/* See if anything is expanded? */
+	expanded = FALSE;
+	g_hash_table_iter_init (&iter, self->pv->items);
+	while (g_hash_table_iter_next (&iter, NULL, &value)) {
+		item = value;
+		if (item->expanded) {
+			expanded = TRUE;
+			break;
+		}
+	}
+
+	/*
+	 * We use a string in our widget font as the basis for our measurements.
+	 * These are just estimates of what we need, and what looks goodish.
+	 * There's room here for improvement. If this is causes problems for
+	 * you or bothers you, scratch that itch:
+	 */
+
+	layout = gtk_widget_create_pango_layout (GTK_WIDGET (self), "0123456789");
+	pango_layout_get_extents (layout, NULL, &extents);
+	pango_extents_to_pixels (&extents, NULL);
+	g_object_unref (layout);
+
+	if (!gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &icon_width, &icon_height)) {
+		icon_width = 48;
+		icon_height = 48;
+	}
+
+	if (expanded) {
+		/* If expanded, display more 10 lines at least */
+		self->pv->minimal_height = extents.height * 14;
+		self->pv->natural_height = extents.height * 25;
+	} else {
+		/* If not expanded we can get by with 9 lines */
+		self->pv->minimal_height = extents.height * 8;
+		self->pv->natural_height = extents.height * 9;
+	}
+
+	self->pv->minimal_width = icon_width + (extents.width * 5);
+	self->pv->natural_width = icon_width + (extents.width * 8);
+	self->pv->have_measurements = TRUE;
+}
+
+#endif /* GTK+ 3 */
+
+static void
+recalculate_and_resize (GcrDisplayView *self)
+{
+	self->pv->have_measurements = FALSE;
+	gtk_widget_queue_resize (GTK_WIDGET (self));
+}
+
 static GtkTextTagTable*
 create_tag_table (GcrDisplayView *self)
 {
@@ -135,6 +210,7 @@ on_expander_expanded (GObject *object, GParamSpec *param_spec, gpointer user_dat
 	GcrDisplayItem *item = user_data;
 	item->expanded = gtk_expander_get_expanded (expander);
 	gcr_renderer_render (item->renderer, GCR_VIEWER (item->display_view));
+	recalculate_and_resize (item->display_view);
 }
 
 static void
@@ -472,6 +548,30 @@ _gcr_display_view_expose_event (GtkWidget *widget, GdkEventExpose *event)
 
 #endif /* GTK 2.x */
 
+#if GTK_CHECK_VERSION (3,0,0)
+
+static void
+_gcr_display_get_preferred_height (GtkWidget *widget, gint *minimal_height,
+                                   gint *natural_height)
+{
+	GcrDisplayView *self = GCR_DISPLAY_VIEW (widget);
+	ensure_measurements (self);
+	*minimal_height = self->pv->minimal_height;
+	*natural_height = self->pv->natural_height;
+}
+
+static void
+_gcr_display_get_preferred_width (GtkWidget *widget, gint *minimal_width,
+                                  gint *natural_width)
+{
+	GcrDisplayView *self = GCR_DISPLAY_VIEW (widget);
+	ensure_measurements (self);
+	*minimal_width = self->pv->minimal_width;
+	*natural_width = self->pv->natural_width;
+}
+
+#endif /* GTK 3.x */
+
 static void
 _gcr_display_view_class_init (GcrDisplayViewClass *klass)
 {
@@ -487,6 +587,11 @@ _gcr_display_view_class_init (GcrDisplayViewClass *klass)
 
 	widget_class->realize = _gcr_display_view_realize;
 
+#if GTK_CHECK_VERSION (3,0,0)
+	widget_class->get_preferred_height = _gcr_display_get_preferred_height;
+	widget_class->get_preferred_width = _gcr_display_get_preferred_width;
+#endif
+
 #if GTK_CHECK_VERSION (2,91,0)
 	widget_class->draw = _gcr_display_view_draw;
 #else
diff --git a/gcr/gcr-viewer.c b/gcr/gcr-viewer.c
index 03a5a4b..498f5b5 100644
--- a/gcr/gcr-viewer.c
+++ b/gcr/gcr-viewer.c
@@ -19,6 +19,7 @@
 
 #include "config.h"
 
+#include "gcr-display-scrolled.h"
 #include "gcr-display-view.h"
 #include "gcr-renderer.h"
 #include "gcr-viewer.h"
@@ -64,6 +65,12 @@ gcr_viewer_new (void)
 	return GCR_VIEWER (_gcr_display_view_new ());
 }
 
+GcrViewer*
+gcr_viewer_new_scrolled (void)
+{
+	return GCR_VIEWER (_gcr_display_scrolled_new ());
+}
+
 void
 gcr_viewer_add_renderer (GcrViewer *self, GcrRenderer *renderer)
 {
diff --git a/gcr/gcr-viewer.h b/gcr/gcr-viewer.h
index 6f53bdb..c4d2040 100644
--- a/gcr/gcr-viewer.h
+++ b/gcr/gcr-viewer.h
@@ -57,6 +57,8 @@ GType                   gcr_viewer_get_type               (void);
 
 GcrViewer*              gcr_viewer_new                    (void);
 
+GcrViewer*              gcr_viewer_new_scrolled           (void);
+
 void                    gcr_viewer_add_renderer           (GcrViewer *self,
                                                            GcrRenderer *renderer);
 
diff --git a/gcr/tests/ui-test-certificate.c b/gcr/tests/ui-test-certificate.c
index cc9b7a6..2a181ac 100644
--- a/gcr/tests/ui-test-certificate.c
+++ b/gcr/tests/ui-test-certificate.c
@@ -68,7 +68,6 @@ on_parser_parsed (GcrParser *parser, gpointer unused)
 	gtk_widget_show (GTK_WIDGET (details));
 	gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), GTK_WIDGET (details));
 
-	gtk_window_set_default_size (GTK_WINDOW (dialog), 550, 400);
 	gtk_container_set_border_width (GTK_CONTAINER (dialog), 20);
 	gtk_dialog_run (dialog);
 	gtk_widget_destroy (GTK_WIDGET (dialog));



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]