summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan Pablo Ugarte <juanpablougarte@gmail.com>2013-07-29 18:56:52 -0300
committerJuan Pablo Ugarte <juanpablougarte@gmail.com>2013-09-25 15:49:55 -0300
commitc5cbf9a6b2f45bfab4658a96c0f06770fd5a7a42 (patch)
treebcc1983f95e4f6268f199be7c26976a3b2aa5212
parent7bf4dc64be6d3df76ea728f38c441b798285789e (diff)
downloadglade-c5cbf9a6b2f45bfab4658a96c0f06770fd5a7a42.tar.gz
Added --slideshow option
Make --screenshot and --slideshow save every widget in a different page if the format supports it (like pdf)
-rw-r--r--gladeui/glade-preview-window.c208
-rw-r--r--gladeui/glade-preview-window.h3
-rw-r--r--gladeui/glade-previewer.c112
3 files changed, 248 insertions, 75 deletions
diff --git a/gladeui/glade-preview-window.c b/gladeui/glade-preview-window.c
index 116ec857..c2fe7193 100644
--- a/gladeui/glade-preview-window.c
+++ b/gladeui/glade-preview-window.c
@@ -108,6 +108,14 @@ glade_preview_window_key_press_event (GtkWidget *widget, GdkEventKey *event)
case GDK_KEY_F8:
extension = priv->extension ? priv->extension : "png";
break;
+ case GDK_KEY_F11:
+ if (gdk_window_get_state (gtk_widget_get_window (widget)) & GDK_WINDOW_STATE_FULLSCREEN)
+ gtk_window_unfullscreen (GTK_WINDOW (widget));
+ else
+ gtk_window_fullscreen (GTK_WINDOW (widget));
+
+ return TRUE;
+ break;
default:
return FALSE;
break;
@@ -334,7 +342,7 @@ check_for_draw (GdkEvent *event, gpointer loop)
/* Taken from Gtk sources gtk-reftest.c */
static void
-wait_for_drawing (GdkWindow *window)
+glade_preview_wait_for_drawing (GdkWindow *window)
{
GMainLoop *loop;
@@ -355,25 +363,70 @@ wait_for_drawing (GdkWindow *window)
g_main_loop_run (loop);
}
-static inline gdouble
-get_x_scale (GdkScreen *screen)
+static const gchar *
+glade_preview_get_extension (const gchar *filename)
{
- return 72.0 / (gdk_screen_get_width (screen) / (gdk_screen_get_width_mm (screen) * 0.03937008));
+ gchar *extension;
+
+ g_return_val_if_fail (filename != NULL, NULL);
+
+ extension = g_strrstr (filename,".");
+
+ if (extension)
+ extension++;
+
+ if (!extension)
+ {
+ g_warning ("%s has no extension!", filename);
+ return NULL;
+ }
+ return extension;
}
-static inline gdouble
-get_y_scale (GdkScreen *screen)
+static void
+glade_preview_get_scale (GdkScreen *screen, gdouble *sx, gdouble *sy)
{
- return 72.0 / (gdk_screen_get_height (screen) / (gdk_screen_get_height_mm (screen) * 0.03937008));
+ if (sx)
+ *sx = 72.0 / (gdk_screen_get_width (screen) / (gdk_screen_get_width_mm (screen) * 0.03937008));
+
+ if (sy)
+ *sy = 72.0 / (gdk_screen_get_height (screen) / (gdk_screen_get_height_mm (screen) * 0.03937008));
}
-typedef enum
+static cairo_surface_t *
+glade_preview_surface_from_file (const gchar *filename, gdouble w, gdouble h)
{
- EXT_TYPE_SVG,
- EXT_TYPE_PS,
- EXT_TYPE_PDF,
- EXT_TYPE_OTHER
-} ExtTypeEnum;
+ cairo_surface_t *surface;
+ const gchar *extension;
+
+ extension = glade_preview_get_extension (filename);
+
+ if (extension == NULL)
+ return NULL;
+
+ if (g_strcmp0 (extension, "svg") == 0)
+#if CAIRO_HAS_SVG_SURFACE
+ surface = cairo_svg_surface_create (filename, w, h);
+#else
+ g_warning ("PDF not supported by the cairo version used");
+#endif
+ else if (g_strcmp0 (extension, "ps") == 0)
+#if CAIRO_HAS_PS_SURFACE
+ surface = cairo_ps_surface_create (filename, w, h);
+#else
+ g_warning ("PS not supported by the cairo version used");
+#endif
+ else if (g_strcmp0 (extension, "pdf") == 0)
+#if CAIRO_HAS_PDF_SURFACE
+ surface = cairo_pdf_surface_create (filename, w, h);
+#else
+ g_warning ("PDF not supported by the cairo version used");
+#endif
+ else
+ return NULL;
+
+ return surface;
+}
/**
* glade_preview_window_screenshot:
@@ -390,10 +443,10 @@ glade_preview_window_screenshot (GladePreviewWindow *window,
const gchar *filename)
{
GladePreviewWindowPrivate *priv;
+ cairo_surface_t *surface;
GdkWindow *gdkwindow;
GdkScreen *screen;
- gchar *extension;
- ExtTypeEnum ext_type;
+ gdouble sx, sy;
gint w, h;
g_return_if_fail (GLADE_IS_PREVIEW_WINDOW (window));
@@ -403,74 +456,99 @@ glade_preview_window_screenshot (GladePreviewWindow *window,
if (!priv->widget)
return;
- extension = g_strrstr (filename,".");
-
- if (extension)
- extension++;
-
- if (!extension)
- {
- g_warning ("%s has no extension!", filename);
- return;
- }
-
gdkwindow = gtk_widget_get_window (priv->widget);
screen = gdk_window_get_screen (gdkwindow);
if (wait)
- wait_for_drawing (gdkwindow);
+ glade_preview_wait_for_drawing (gdkwindow);
w = gtk_widget_get_allocated_width (priv->widget);
h = gtk_widget_get_allocated_height (priv->widget);
+ glade_preview_get_scale (screen, &sx, &sy);
+
+ surface = glade_preview_surface_from_file (filename, w*sx, h*sy);
- if (g_strcmp0 (extension, "svg") == 0)
- ext_type = EXT_TYPE_SVG;
- else if (g_strcmp0 (extension, "ps") == 0)
- ext_type = EXT_TYPE_PS;
- else if (g_strcmp0 (extension, "pdf") == 0)
- ext_type = EXT_TYPE_PDF;
+ if (surface)
+ {
+ cairo_t *cr = cairo_create (surface);
+ cairo_scale (cr, sx, sy);
+ gtk_widget_draw (priv->widget, cr);
+ cairo_destroy (cr);
+ cairo_surface_destroy(surface);
+ }
else
- ext_type = EXT_TYPE_OTHER;
-
- if (ext_type == EXT_TYPE_OTHER)
{
GdkPixbuf *pix = gdk_pixbuf_get_from_window (gdkwindow, 0, 0, w, h);
-
- gdk_pixbuf_save (pix, filename, extension, NULL, NULL);
+ const gchar *ext = glade_preview_get_extension (filename);
+ GError *error = NULL;
+
+ if (gdk_pixbuf_save (pix, filename, ext ? ext : "png", &error, NULL))
+ {
+ g_warning ("Could not save screenshot to %s because %s", filename, error->message);
+ g_error_free (error);
+ }
g_object_unref (pix);
}
- else
+}
+
+/**
+ * glade_preview_window_slideshow_save:
+ * @window: A GladePreviewWindow
+ * @filename: a filename to save the slideshow.
+ *
+ * Takes a screenshot of every widget GtkStack children and save it to @filename
+ * each in a different page
+ */
+void
+glade_preview_window_slideshow_save (GladePreviewWindow *window,
+ const gchar *filename)
+{
+ GladePreviewWindowPrivate *priv;
+ cairo_surface_t *surface;
+ GdkWindow *gdkwindow;
+ GtkStack *stack;
+ gdouble sx, sy;
+
+ g_return_if_fail (GLADE_IS_PREVIEW_WINDOW (window));
+ g_return_if_fail (filename != NULL);
+ priv = window->priv;
+
+ g_return_if_fail (priv->widget);
+ g_return_if_fail (GTK_IS_STACK (priv->widget));
+ stack = GTK_STACK (priv->widget);
+
+ gdkwindow = gtk_widget_get_window (priv->widget);
+ glade_preview_wait_for_drawing (gdkwindow);
+
+ glade_preview_get_scale (gtk_widget_get_screen (GTK_WIDGET (window)), &sx, &sy);
+ surface = glade_preview_surface_from_file (filename,
+ gtk_widget_get_allocated_width (GTK_WIDGET (stack))*sx,
+ gtk_widget_get_allocated_height (GTK_WIDGET (stack))*sy);
+
+ if (surface)
{
- cairo_surface_t *surface;
- cairo_t *cr;
- gdouble sx = get_x_scale (screen);
- gdouble sy = get_y_scale (screen);
+ GList *l, *children = gtk_container_get_children (GTK_CONTAINER (stack));
+ cairo_t *cr= cairo_create (surface);
- if (ext_type == EXT_TYPE_SVG)
-#if CAIRO_HAS_SVG_SURFACE
- surface = cairo_svg_surface_create (filename, w*sx, h*sy);
-#else
- g_warning ("PDF not supported by the cairo version used");
-#endif
- else if (ext_type == EXT_TYPE_PS)
-#if CAIRO_HAS_PS_SURFACE
- surface = cairo_ps_surface_create (filename, w*sx, h*sy);
-#else
- g_warning ("PS not supported by the cairo version used");
-#endif
- else if (ext_type == EXT_TYPE_PDF)
-#if CAIRO_HAS_PDF_SURFACE
- surface = cairo_pdf_surface_create (filename, w*sx, h*sy);
-#else
- g_warning ("PDF not supported by the cairo version used");
-#endif
-
- cr = cairo_create (surface);
cairo_scale (cr, sx, sy);
- gtk_widget_draw (priv->widget, cr);
+
+ for (l = children; l; l = g_list_next (l))
+ {
+ GtkWidget *child = l->data;
+ gtk_stack_set_visible_child (stack, child);
+ glade_preview_wait_for_drawing (gdkwindow);
+ gtk_widget_draw (child, cr);
+ cairo_show_page (cr);
+ }
+
+ if (children)
+ gtk_stack_set_visible_child (stack, children->data);
+
+ g_list_free (children);
cairo_destroy (cr);
cairo_surface_destroy(surface);
-
}
+ else
+ g_warning ("Could not save slideshow to %s", filename);
}
diff --git a/gladeui/glade-preview-window.h b/gladeui/glade-preview-window.h
index 7ed54f89..0ff2bdcd 100644
--- a/gladeui/glade-preview-window.h
+++ b/gladeui/glade-preview-window.h
@@ -73,6 +73,9 @@ void glade_preview_window_screenshot (GladePreviewWindow *window,
gboolean wait,
const gchar *filename);
+void glade_preview_window_slideshow_save (GladePreviewWindow *window,
+ const gchar *filename);
+
G_END_DECLS
#endif /* _GLADE_PREVIEW_WINDOW_H_ */
diff --git a/gladeui/glade-previewer.c b/gladeui/glade-previewer.c
index 4a428d0f..30f17263 100644
--- a/gladeui/glade-previewer.c
+++ b/gladeui/glade-previewer.c
@@ -45,12 +45,12 @@ get_toplevel (GtkBuilder *builder, gchar *name)
if (name == NULL)
{
- GSList *objects;
+ GSList *l, *objects = gtk_builder_get_objects (builder);
/* Iterate trough objects and search for a window or widget */
- for (objects = gtk_builder_get_objects (builder); objects; objects = g_slist_next (objects))
+ for (l = objects; l; l = g_slist_next (l))
{
- GObject *obj = objects->data;
+ GObject *obj = l->data;
if (!GTK_IS_WIDGET (obj) || gtk_widget_get_parent (GTK_WIDGET (obj)))
continue;
@@ -289,8 +289,56 @@ glade_previewer_free (GladePreviewer *app)
g_free (app);
}
+static gint
+objects_cmp_func (gconstpointer a, gconstpointer b)
+{
+ const gchar *name_a, *name_b;
+ name_a = gtk_buildable_get_name (GTK_BUILDABLE (a));
+ name_b = gtk_buildable_get_name (GTK_BUILDABLE (b));
+ return g_strcmp0 (name_a, name_b);
+}
+static gboolean
+glade_previewer_stack_key_press_event (GtkWidget *window, GdkEventKey *event, GtkWidget *widget)
+{
+ GtkWidget *child = gtk_stack_get_visible_child (GTK_STACK (widget));
+ GList *children, *node;
+ gboolean retval;
+
+ if (!child)
+ return FALSE;
+
+ children = gtk_container_get_children (GTK_CONTAINER (widget));
+
+ node = g_list_find (children, child);
+
+ if (node)
+ {
+ switch (event->keyval)
+ {
+ case GDK_KEY_Page_Up:
+ if (node->prev)
+ gtk_stack_set_visible_child (GTK_STACK (widget), node->prev->data);
+ retval = TRUE;
+ break;
+ case GDK_KEY_Page_Down:
+ if (node->next)
+ gtk_stack_set_visible_child (GTK_STACK (widget), node->next->data);
+ retval = TRUE;
+ break;
+ default:
+ retval = FALSE;
+ break;
+ }
+ }
+
+ g_list_free (children);
+ return retval;
+}
+
+
static gboolean listen = FALSE;
static gboolean version = FALSE;
+static gboolean slideshow = FALSE;
static gchar *file_name = NULL;
static gchar *toplevel_name = NULL;
static gchar *css_file_name = NULL;
@@ -303,6 +351,7 @@ static GOptionEntry option_entries[] =
{"screenshot", 0, 0, G_OPTION_ARG_FILENAME, &screenshot_file_name, N_("File name to save a screenshot"), NULL},
{"css", 0, 0, G_OPTION_ARG_FILENAME, &css_file_name, N_("CSS file to use"), NULL},
{"listen", 'l', 0, G_OPTION_ARG_NONE, &listen, N_("Listen standard input"), NULL},
+ {"slideshow", 0, 0, G_OPTION_ARG_NONE, &slideshow, N_("make a slideshow of every toplevel widget by adding them in a GtkStack"), NULL},
{"version", 'v', 0, G_OPTION_ARG_NONE, &version, N_("Display previewer version"), NULL},
{NULL}
};
@@ -373,7 +422,6 @@ main (int argc, char **argv)
{
GtkBuilder *builder = gtk_builder_new ();
GError *error = NULL;
- GtkWidget *widget;
/* Use from_file() function gives builder a chance to know where to load resources from */
if (!gtk_builder_add_from_file (builder, app->file_name, &error))
@@ -383,14 +431,58 @@ main (int argc, char **argv)
return 1;
}
- widget = get_toplevel (builder, toplevel_name);
- glade_preview_window_set_widget (app->window, widget);
- gtk_widget_show (widget);
+ if (slideshow)
+ {
+ GSList *l, *objects = gtk_builder_get_objects (builder);
+ GtkStack *stack = GTK_STACK (gtk_stack_new ());
+
+ /* Add Page up and Page down key binding */
+ g_signal_connect (app->window, "key-press-event",
+ G_CALLBACK (glade_previewer_stack_key_press_event),
+ stack);
+
+ objects = g_slist_sort (objects, objects_cmp_func);
+
+ for (l = objects; l; l = g_slist_next (l))
+ {
+ GObject *obj = l->data;
+
+ if (!GTK_IS_WIDGET (obj) || gtk_widget_get_parent (GTK_WIDGET (obj)))
+ continue;
- if (screenshot_file_name)
- glade_preview_window_screenshot (app->window, TRUE, screenshot_file_name);
+ /* TODO: make sure we can add a toplevel inside a stack */
+ if (GTK_IS_WINDOW (obj))
+ continue;
+
+ gtk_stack_add_named (stack, GTK_WIDGET (obj),
+ gtk_buildable_get_name (GTK_BUILDABLE (obj)));
+ }
+
+ glade_preview_window_set_widget (app->window, GTK_WIDGET (stack));
+ gtk_widget_show (GTK_WIDGET (stack));
+
+ if (screenshot_file_name)
+ glade_preview_window_slideshow_save (app->window, screenshot_file_name);
+ else
+ {
+ gtk_stack_set_transition_type (stack, GTK_STACK_TRANSITION_TYPE_CROSSFADE);
+
+ gtk_main ();
+ }
+
+ g_slist_free (objects);
+ }
else
- gtk_main ();
+ {
+ GtkWidget *widget = get_toplevel (builder, toplevel_name);
+ glade_preview_window_set_widget (app->window, widget);
+ gtk_widget_show (widget);
+
+ if (screenshot_file_name)
+ glade_preview_window_screenshot (app->window, TRUE, screenshot_file_name);
+ else
+ gtk_main ();
+ }
g_object_unref (builder);
}