From f5c33374de28b3e39fdb87042e83ce77ff93e96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Poo-Caama=C3=B1o?= Date: Mon, 28 Oct 2013 22:38:21 -0700 Subject: [PATCH] glib-demo: Add simple demo to add line annotations Set the color before adding an annotation instead of assigning one by default and allowing a later modification. --- glib/demo/annots.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 202 insertions(+), 10 deletions(-) diff --git a/glib/demo/annots.c b/glib/demo/annots.c index 63e0136..4aadee2 100644 --- a/glib/demo/annots.c +++ b/glib/demo/annots.c @@ -52,6 +52,7 @@ typedef enum { typedef struct { PopplerDocument *doc; PopplerPage *page; + PopplerAnnot *active_annot; GtkWidget *tree_view; GtkListStore *model; @@ -67,10 +68,12 @@ typedef struct { ModeType mode; cairo_surface_t *surface; + PopplerColor *annot_color; GdkPoint start; GdkPoint stop; GdkCursorType cursor; + guint annotations_idle; } PgdAnnotsDemo; static void pgd_annots_viewer_queue_redraw (PgdAnnotsDemo *demo); @@ -81,6 +84,11 @@ pgd_annots_free (PgdAnnotsDemo *demo) if (!demo) return; + if (demo->annotations_idle > 0) { + g_source_remove (demo->annotations_idle); + demo->annotations_idle = 0; + } + if (demo->doc) { g_object_unref (demo->doc); demo->doc = NULL; @@ -96,6 +104,11 @@ pgd_annots_free (PgdAnnotsDemo *demo) demo->model = NULL; } + if (demo->annot_color) { + g_free (demo->annot_color); + demo->annot_color = NULL; + } + g_free (demo); } @@ -353,6 +366,10 @@ pgd_annots_start_add_annot (GtkWidget *button, demo->mode = MODE_ADD; pgd_annots_update_cursor (demo, GDK_TCROSS); break; + case POPPLER_ANNOT_LINE: + demo->mode = MODE_DRAWING; + pgd_annots_update_cursor (demo, GDK_TCROSS); + break; default: g_printerr ("Annotation not implemented: %d\n", demo->annot_type); return; @@ -441,6 +458,45 @@ pgd_annot_view_set_annot_text (GtkWidget *table, } static void +pgd_annot_color_changed (GtkButton *button, + GParamSpec *pspec, + PgdAnnotsDemo *demo) +{ + GdkRGBA color; + +#if GTK_CHECK_VERSION(3,4,0) + gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (button), &color); +#else + gtk_color_button_get_rgba (GTK_COLOR_BUTTON (button), &color); +#endif + demo->annot_color->red = CLAMP ((guint) (color.red * 65535), 0, 65535); + demo->annot_color->green = CLAMP ((guint) (color.green * 65535), 0, 65535); + demo->annot_color->blue = CLAMP ((guint) (color.blue * 65535), 0, 65535); +} + +static void +pgd_annot_view_set_annot_line (PgdAnnotsDemo *demo, + GtkWidget *table, + PopplerAnnot *annot, + gint *row) +{ + PopplerColor *poppler_color; + GdkPixbuf *pixbuf; + GtkWidget *image; + + if ((poppler_color = poppler_annot_get_color (annot))) { + demo->active_annot = annot; + + pixbuf = pgd_pixbuf_new_for_color (poppler_color); + image = gtk_image_new (); + gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf); + g_object_unref (pixbuf); + + pgd_table_add_property_with_custom_widget (GTK_GRID (table), "Color:", image, row); + } +} + +static void pgd_annot_view_set_annot_free_text (GtkWidget *table, PopplerAnnotFreeText *annot, gint *row) @@ -613,6 +669,9 @@ pgd_annot_view_set_annot (PgdAnnotsDemo *demo, case POPPLER_ANNOT_TEXT: pgd_annot_view_set_annot_text (table, POPPLER_ANNOT_TEXT (annot), &row); break; + case POPPLER_ANNOT_LINE: + pgd_annot_view_set_annot_line (demo, table, annot, &row); + break; case POPPLER_ANNOT_FREE_TEXT: pgd_annot_view_set_annot_free_text (table, POPPLER_ANNOT_FREE_TEXT (annot), &row); break; @@ -633,7 +692,7 @@ pgd_annot_view_set_annot (PgdAnnotsDemo *demo, gtk_widget_show (table); } -static void +static GtkTreeIter pgd_annots_add_annot_to_model (PgdAnnotsDemo *demo, PopplerAnnot *annot, PopplerRectangle area) @@ -672,6 +731,8 @@ pgd_annots_add_annot_to_model (PgdAnnotsDemo *demo, g_free (y1); g_free (x2); g_free (y2); + + return iter; } static void @@ -815,28 +876,44 @@ static void pgd_annots_add_annotation (PgdAnnotsDemo *demo) { PopplerRectangle rect; + PopplerPoint start, end; PopplerAnnot *annot; gdouble width, height; + GtkTreeIter iter; + GtkTreePath *path; poppler_page_get_size (demo->page, &width, &height); - rect.x1 = demo->start.x; - rect.y1 = height - demo->start.y; - rect.x2 = demo->stop.x; - rect.y2 = height - demo->stop.y; + rect.x1 = start.x = demo->start.x; + rect.y1 = start.y = height - demo->start.y; + rect.x2 = end.x = demo->stop.x; + rect.y2 = end.y = height - demo->stop.y; + switch (demo->annot_type) { case POPPLER_ANNOT_TEXT: annot = poppler_annot_text_new (demo->doc, &rect); - poppler_page_add_annot (demo->page, annot); - pgd_annots_add_annot_to_model (demo, annot, rect); + break; + case POPPLER_ANNOT_LINE: + annot = poppler_annot_line_new (demo->doc, &rect); + poppler_annot_line_set_vertices (POPPLER_ANNOT_LINE (annot), + start, end); break; default: g_printerr ("Annotation not implemented: %d\n", demo->annot_type); return; } + demo->active_annot = annot; + + poppler_annot_set_color (annot, demo->annot_color); + poppler_page_add_annot (demo->page, annot); + iter = pgd_annots_add_annot_to_model (demo, annot, rect); + pgd_annots_viewer_queue_redraw (demo); - demo->mode = MODE_NORMAL; + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (demo->model), &iter); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (demo->tree_view), path, NULL, FALSE); + gtk_tree_path_free (path); } /* Render area */ @@ -903,6 +980,8 @@ pgd_annots_viewer_redraw (PgdAnnotsDemo *demo) gtk_widget_queue_draw (demo->darea); + demo->annotations_idle = 0; + return FALSE; } @@ -938,11 +1017,90 @@ pgd_annots_drawing_area_button_press (GtkWidget *area, demo->start.y = event->y; demo->stop = demo->start; - if (demo->mode == MODE_ADD) { - pgd_annots_add_annotation (demo); + switch (demo->mode) { + case MODE_ADD: + pgd_annots_add_annotation (demo); + pgd_annots_update_cursor (demo, GDK_LAST_CURSOR); + demo->mode = MODE_NORMAL; + break; + case MODE_DRAWING: + pgd_annots_add_annotation (demo); + default: + break; + } + + return TRUE; +} + +static gboolean +pgd_annots_drawing_area_motion_notify (GtkWidget *area, + GdkEventMotion *event, + PgdAnnotsDemo *demo) +{ + if (!demo->page || demo->mode == MODE_NORMAL || demo->mode == MODE_ADD) + return FALSE; + + if (demo->start.x != -1) { + demo->stop.x = event->x; + demo->stop.y = event->y; + + if (demo->mode == MODE_DRAWING) { + PopplerRectangle rect; + PopplerPoint start, end; + gdouble width, height; + + poppler_page_get_size (demo->page, &width, &height); + + /* Keep the drawing within the page */ + demo->stop.x = MAX (demo->stop.x, 0); + demo->stop.y = MAX (demo->stop.y, 0); + demo->stop.x = MIN (demo->stop.x, width); + demo->stop.y = MIN (demo->stop.y, height); + + rect.x1 = start.x = demo->start.x; + rect.y1 = start.y = height - demo->start.y; + rect.x2 = end.x = demo->stop.x; + rect.y2 = end.y = height - demo->stop.y; + + poppler_annot_set_rectangle (demo->active_annot, rect); + poppler_annot_line_set_vertices (POPPLER_ANNOT_LINE (demo->active_annot), + start, end); + + pgd_annot_view_set_annot (demo, demo->active_annot); + if (demo->annotations_idle == 0) { + demo->annotations_idle = + g_idle_add ((GSourceFunc)pgd_annots_viewer_redraw, + demo); + } + } + } + + return TRUE; +} + +static gboolean +pgd_annots_drawing_area_button_release (GtkWidget *area, + GdkEventButton *event, + PgdAnnotsDemo *demo) +{ + if (!demo->page || demo->mode == MODE_NORMAL || demo->mode == MODE_ADD) + return FALSE; + + if (event->button != 1) + return FALSE; + + if (demo->start.x != -1) { + demo->mode = MODE_NORMAL; pgd_annots_update_cursor (demo, GDK_LAST_CURSOR); } + demo->start.x = -1; + + if (demo->annotations_idle > 0) { + g_source_remove (demo->annotations_idle); + demo->annotations_idle = 0; + } + return TRUE; } @@ -962,6 +1120,7 @@ pgd_annots_create_widget (PopplerDocument *document) GtkTreeViewColumn *column; GtkListStore *model; GtkTreeIter iter; + GdkRGBA rgba; gchar *str; gint n_pages; @@ -1019,6 +1178,12 @@ pgd_annots_create_widget (PopplerDocument *document) SELECTED_TYPE_COLUMN, POPPLER_ANNOT_TEXT, SELECTED_LABEL_COLUMN, "Text", -1); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + SELECTED_TYPE_COLUMN, POPPLER_ANNOT_LINE, + SELECTED_LABEL_COLUMN, "Line", + -1); demo->type_selector = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model)); g_object_unref (model); @@ -1031,6 +1196,27 @@ pgd_annots_create_widget (PopplerDocument *document) gtk_box_pack_end (GTK_BOX (hbox), demo->type_selector, FALSE, FALSE, 0); gtk_widget_show (demo->type_selector); + demo->annot_color = poppler_color_new (); + demo->annot_color->red = 65535; + demo->annot_color->green = 0; + demo->annot_color->blue = 0; + rgba.red = demo->annot_color->red; + rgba.green = demo->annot_color->green; + rgba.blue = demo->annot_color->blue; + rgba.alpha = 1.0; + + button = gtk_color_button_new (); +#if GTK_CHECK_VERSION(3,4,0) + gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (button), &rgba); +#else + gtk_color_button_set_rgba (GTK_COLOR_BUTTON (button), &rgba); +#endif + g_signal_connect (button, "notify::color", + G_CALLBACK (pgd_annot_color_changed), + (gpointer)demo); + gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, TRUE, 0); + gtk_widget_show (button); + gtk_widget_show (hbox); demo->timer_label = gtk_label_new (NULL); @@ -1154,6 +1340,12 @@ pgd_annots_create_widget (PopplerDocument *document) g_signal_connect (demo->darea, "button_press_event", G_CALLBACK (pgd_annots_drawing_area_button_press), (gpointer)demo); + g_signal_connect (demo->darea, "motion_notify_event", + G_CALLBACK (pgd_annots_drawing_area_motion_notify), + (gpointer)demo); + g_signal_connect (demo->darea, "button_release_event", + G_CALLBACK (pgd_annots_drawing_area_button_release), + (gpointer)demo); swindow = gtk_scrolled_window_new (NULL, NULL); #if GTK_CHECK_VERSION(3, 7, 8) -- 1.7.9.5