[gnome-keyring] Calculate the minimal/natural size of certificate widget better.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] Calculate the minimal/natural size of certificate widget better.
- Date: Fri, 4 Mar 2011 18:07:18 +0000 (UTC)
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]