From 492e4447f2e50f3f5a3d018e670900c01e1b20e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Poo-Caama=C3=B1o?= Date: Mon, 30 Sep 2013 01:29:27 -0700 Subject: [PATCH 3/3] glib: Add annotations interactively in demo * Prepare UI to add multiple annotations type in demo * Remove dialog and button add annotations. --- glib/demo/annots.c | 340 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 198 insertions(+), 142 deletions(-) diff --git a/glib/demo/annots.c b/glib/demo/annots.c index 3c740bc..4348d60 100644 --- a/glib/demo/annots.c +++ b/glib/demo/annots.c @@ -22,6 +22,8 @@ #include "annots.h" #include "utils.h" +#define ANNOTS_NONE 0 + enum { ANNOTS_X1_COLUMN, ANNOTS_Y1_COLUMN, @@ -36,6 +38,12 @@ enum { N_COLUMNS }; +enum { + SELECTED_TYPE_COLUMN, + SELECTED_LABEL_COLUMN, + SELECTED_N_COLUMNS +}; + typedef struct { PopplerDocument *doc; PopplerPage *page; @@ -47,8 +55,12 @@ typedef struct { GtkWidget *timer_label; gint num_page; + gint selected_type; cairo_surface_t *surface; + + GdkPoint start; + GdkPoint stop; } PgdAnnotsDemo; static void pgd_annots_viewer_queue_redraw (PgdAnnotsDemo *demo); @@ -565,6 +577,47 @@ pgd_annot_view_set_annot (PgdAnnotsDemo *demo, } static void +pgd_annots_add_annot_to_model (PgdAnnotsDemo *demo, + PopplerAnnot *annot, + PopplerRectangle area) +{ + GtkTreeIter iter; + GdkPixbuf *pixbuf; + PopplerAnnotFlag flags; + gchar *x1, *y1, *x2, *y2; + + x1 = g_strdup_printf ("%.2f", area.x1); + y1 = g_strdup_printf ("%.2f", area.y1); + x2 = g_strdup_printf ("%.2f", area.x2); + y2 = g_strdup_printf ("%.2f", area.y2); + + pixbuf = get_annot_color (annot); + flags = poppler_annot_get_flags (annot); + + gtk_list_store_append (demo->model, &iter); + gtk_list_store_set (demo->model, &iter, + ANNOTS_X1_COLUMN, x1, + ANNOTS_Y1_COLUMN, y1, + ANNOTS_X2_COLUMN, x2, + ANNOTS_Y2_COLUMN, y2, + ANNOTS_TYPE_COLUMN, get_annot_type (annot), + ANNOTS_COLOR_COLUMN, pixbuf, + ANNOTS_FLAG_INVISIBLE_COLUMN, (flags & POPPLER_ANNOT_FLAG_INVISIBLE), + ANNOTS_FLAG_HIDDEN_COLUMN, (flags & POPPLER_ANNOT_FLAG_HIDDEN), + ANNOTS_FLAG_PRINT_COLUMN, (flags & POPPLER_ANNOT_FLAG_PRINT), + ANNOTS_COLUMN, annot, + -1); + + if (pixbuf) + g_object_unref (pixbuf); + + g_free (x1); + g_free (y1); + g_free (x2); + g_free (y2); +} + +static void pgd_annots_get_annots (PgdAnnotsDemo *demo) { GList *mapping, *l; @@ -603,42 +656,9 @@ pgd_annots_get_annots (PgdAnnotsDemo *demo) for (l = mapping; l; l = g_list_next (l)) { PopplerAnnotMapping *amapping; - GtkTreeIter iter; - gchar *x1, *y1, *x2, *y2; - GdkPixbuf *pixbuf; - PopplerAnnotFlag flags; amapping = (PopplerAnnotMapping *) l->data; - - x1 = g_strdup_printf ("%.2f", amapping->area.x1); - y1 = g_strdup_printf ("%.2f", amapping->area.y1); - x2 = g_strdup_printf ("%.2f", amapping->area.x2); - y2 = g_strdup_printf ("%.2f", amapping->area.y2); - - pixbuf = get_annot_color (amapping->annot); - flags = poppler_annot_get_flags (amapping->annot); - - gtk_list_store_append (demo->model, &iter); - gtk_list_store_set (demo->model, &iter, - ANNOTS_X1_COLUMN, x1, - ANNOTS_Y1_COLUMN, y1, - ANNOTS_X2_COLUMN, x2, - ANNOTS_Y2_COLUMN, y2, - ANNOTS_TYPE_COLUMN, get_annot_type (amapping->annot), - ANNOTS_COLOR_COLUMN, pixbuf, - ANNOTS_FLAG_INVISIBLE_COLUMN, (flags & POPPLER_ANNOT_FLAG_INVISIBLE), - ANNOTS_FLAG_HIDDEN_COLUMN, (flags & POPPLER_ANNOT_FLAG_HIDDEN), - ANNOTS_FLAG_PRINT_COLUMN, (flags & POPPLER_ANNOT_FLAG_PRINT), - ANNOTS_COLUMN, amapping->annot, - -1); - - if (pixbuf) - g_object_unref (pixbuf); - - g_free (x1); - g_free (y1); - g_free (x2); - g_free (y2); + pgd_annots_add_annot_to_model (demo, amapping->annot, amapping->area); } poppler_page_free_annot_mapping (mapping); @@ -654,6 +674,21 @@ pgd_annots_page_selector_value_changed (GtkSpinButton *spinbutton, } static void +pgd_annots_type_selector_changed (GtkComboBox *widget, + PgdAnnotsDemo *demo) +{ + GtkTreeModel *model; + GtkTreeIter iter; + + if (gtk_combo_box_get_active_iter (widget, &iter)) { + model = gtk_combo_box_get_model (widget); + gtk_tree_model_get (model, &iter, + SELECTED_TYPE_COLUMN, &(demo->selected_type), + -1); + } +} + +static void pgd_annots_selection_changed (GtkTreeSelection *treeselection, PgdAnnotsDemo *demo) { @@ -732,113 +767,33 @@ pgd_annots_invisible_flag_toggled (GtkCellRendererToggle *renderer, } static void -pgd_annots_add_annot (GtkWidget *button, - PgdAnnotsDemo *demo) +pgd_annots_add_annotation (PgdAnnotsDemo *demo) { - GtkWidget *hbox, *vbox; - GtkWidget *type_selector; - GtkWidget *label; - GtkWidget *rect_hbox; - GtkWidget *rect_x1, *rect_y1, *rect_x2, *rect_y2; - GtkWidget *dialog; - PopplerPage *page; - gdouble width, height; - PopplerAnnot *annot; - PopplerRectangle rect; - - page = poppler_document_get_page (demo->doc, demo->num_page); - if (!page) - return; - poppler_page_get_size (page, &width, &height); - - dialog = gtk_dialog_new_with_buttons ("Add new annotation", - GTK_WINDOW (gtk_widget_get_toplevel (button)), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - "Add annotation", GTK_RESPONSE_ACCEPT, - NULL); - - vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); - - type_selector = gtk_combo_box_text_new (); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (type_selector), "POPPLER_ANNOT_UNKNOWN"); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (type_selector), "POPPLER_ANNOT_TEXT"); - gtk_combo_box_set_active (GTK_COMBO_BOX (type_selector), 1); - gtk_box_pack_start (GTK_BOX (vbox), type_selector, TRUE, TRUE, 0); - gtk_widget_show (type_selector); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - - rect_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - - label = gtk_label_new ("x1:"); - gtk_box_pack_start (GTK_BOX (rect_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - - rect_x1 = gtk_spin_button_new_with_range (0, width, 1.0); - gtk_box_pack_start (GTK_BOX (rect_hbox), rect_x1, TRUE, TRUE, 0); - gtk_widget_show (rect_x1); - - gtk_box_pack_start (GTK_BOX (hbox), rect_hbox, FALSE, TRUE, 0); - gtk_widget_show (rect_hbox); - - rect_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - - label = gtk_label_new ("x2:"); - gtk_box_pack_start (GTK_BOX (rect_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - - rect_x2 = gtk_spin_button_new_with_range (0, width, 1.0); - gtk_box_pack_start (GTK_BOX (rect_hbox), rect_x2, TRUE, TRUE, 0); - gtk_widget_show (rect_x2); - - gtk_box_pack_start (GTK_BOX (hbox), rect_hbox, FALSE, TRUE, 0); - gtk_widget_show (rect_hbox); - - rect_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - - label = gtk_label_new ("y1:"); - gtk_box_pack_start (GTK_BOX (rect_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - - rect_y1 = gtk_spin_button_new_with_range (0, height, 1.0); - gtk_box_pack_start (GTK_BOX (rect_hbox), rect_y1, TRUE, TRUE, 0); - gtk_widget_show (rect_y1); - - gtk_box_pack_start (GTK_BOX (hbox), rect_hbox, FALSE, TRUE, 0); - gtk_widget_show (rect_hbox); - - rect_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - - label = gtk_label_new ("y2:"); - gtk_box_pack_start (GTK_BOX (rect_hbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); + PopplerRectangle rect; + PopplerAnnot *annot; + gdouble width, height; - rect_y2 = gtk_spin_button_new_with_range (0, height, 1.0); - gtk_box_pack_start (GTK_BOX (rect_hbox), rect_y2, TRUE, TRUE, 0); - gtk_widget_show (rect_y2); - - gtk_box_pack_start (GTK_BOX (hbox), rect_hbox, FALSE, TRUE, 0); - gtk_widget_show (rect_hbox); - - gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - gtk_dialog_run (GTK_DIALOG (dialog)); - - rect.x1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON (rect_x1)); - rect.x2 = gtk_spin_button_get_value (GTK_SPIN_BUTTON (rect_x2)); - rect.y1 = height - gtk_spin_button_get_value (GTK_SPIN_BUTTON (rect_y1)); - rect.y2 = height - gtk_spin_button_get_value (GTK_SPIN_BUTTON (rect_y2)); - annot = poppler_annot_text_new (demo->doc, &rect); - poppler_page_add_annot (page, annot); + if (demo->selected_type == ANNOTS_NONE) + return; - g_object_unref (page); + poppler_page_get_size (demo->page, &width, &height); - gtk_widget_destroy (dialog); + rect.x1 = demo->start.x; + rect.y1 = height - demo->start.y; + rect.x2 = demo->stop.x; + rect.y2 = height - demo->stop.y; + switch (demo->selected_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; + default: + g_printerr ("Annotation not implemented: %d\n", demo->selected_type); + return; + } pgd_annots_viewer_queue_redraw (demo); - pgd_annots_get_annots (demo); } /* Render area */ @@ -914,6 +869,71 @@ pgd_annots_viewer_queue_redraw (PgdAnnotsDemo *demo) g_idle_add ((GSourceFunc)pgd_annots_viewer_redraw, demo); } +static void +pgd_annots_drawing_area_realize (GtkWidget *area, + PgdAnnotsDemo *demo) +{ + gtk_widget_add_events (area, + GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON1_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK); +} + +static gboolean +pgd_annots_drawing_area_button_press (GtkWidget *area, + GdkEventButton *event, + PgdAnnotsDemo *demo) +{ + if (!demo->page || demo->selected_type == ANNOTS_NONE) + return FALSE; + + if (event->button != 1) + return FALSE; + + demo->start.x = event->x; + demo->start.y = event->y; + demo->stop = demo->start; + + return TRUE; +} + +static gboolean +pgd_annots_drawing_area_motion_notify (GtkWidget *area, + GdkEventMotion *event, + PgdAnnotsDemo *demo) +{ + if (!demo->page || demo->selected_type == ANNOTS_NONE) + return FALSE; + + if (demo->start.x != -1) { + demo->stop.x = event->x; + demo->stop.y = event->y; + } + + return TRUE; +} + +static gboolean +pgd_annots_drawing_area_button_release (GtkWidget *area, + GdkEventButton *event, + PgdAnnotsDemo *demo) +{ + if (!demo->page || demo->selected_type == ANNOTS_NONE) + return FALSE; + + if (event->button != 1) + return FALSE; + + if (demo->start.x != -1) { + pgd_annots_add_annotation (demo); + } + + demo->start.x = -1; + + return TRUE; +} + /* Main UI */ GtkWidget * pgd_annots_create_widget (PopplerDocument *document) @@ -925,9 +945,12 @@ pgd_annots_create_widget (PopplerDocument *document) GtkWidget *hbox, *page_selector; GtkWidget *hpaned; GtkWidget *swindow, *treeview; + GtkWidget *type_selector; GtkTreeSelection *selection; GtkCellRenderer *renderer; GtkTreeViewColumn *column; + GtkListStore *model; + GtkTreeIter iter; gchar *str; gint n_pages; @@ -966,14 +989,35 @@ pgd_annots_create_widget (PopplerDocument *document) gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 6); gtk_widget_show (button); - button = gtk_button_new_with_label ("Add Annotation"); - g_signal_connect (G_OBJECT (button), "clicked", - G_CALLBACK (pgd_annots_add_annot), - (gpointer) demo); - gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0); - gtk_widget_show (button); - gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0); + + model = gtk_list_store_new(SELECTED_N_COLUMNS, + G_TYPE_INT, G_TYPE_STRING); + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + SELECTED_TYPE_COLUMN, ANNOTS_NONE, + SELECTED_LABEL_COLUMN, "Add annotation:", + -1); + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + SELECTED_TYPE_COLUMN, POPPLER_ANNOT_TEXT, + SELECTED_LABEL_COLUMN, "Text", + -1); + type_selector = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model)); + g_object_unref (model); + + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (type_selector), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (type_selector), renderer, + "text", SELECTED_LABEL_COLUMN, + NULL); + g_signal_connect (G_OBJECT (type_selector), "changed", + G_CALLBACK (pgd_annots_type_selector_changed), + (gpointer) demo); + gtk_combo_box_set_active (GTK_COMBO_BOX (type_selector), 0); + gtk_box_pack_end (GTK_BOX (hbox), type_selector, FALSE, FALSE, 0); + gtk_widget_show (type_selector); + gtk_widget_show (hbox); demo->timer_label = gtk_label_new (NULL); @@ -1091,6 +1135,18 @@ pgd_annots_create_widget (PopplerDocument *document) g_signal_connect (demo->darea, "draw", G_CALLBACK (pgd_annots_view_drawing_area_draw), demo); + g_signal_connect (demo->darea, "realize", + G_CALLBACK (pgd_annots_drawing_area_realize), + (gpointer)demo); + 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