[poppler] glib/demo
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Sun Nov 17 03:29:45 PST 2013
glib/demo/annots.c | 348 ++++++++++++++++++++++++++++++++---------------------
1 file changed, 213 insertions(+), 135 deletions(-)
New commits:
commit 07c255482f7ec8a8cfd4eaeaf7b07de317bbcc7a
Author: Germán Poo-Caamaño <gpoo at gnome.org>
Date: Sun Oct 27 13:30:22 2013 -0700
glib-demo: Add annotations interactively
* Prepare UI to add multiple annotations type.
* Remove dialog and button add annotations.
https://bugs.freedesktop.org/show_bug.cgi?id=69978
diff --git a/glib/demo/annots.c b/glib/demo/annots.c
index 0708abf..c5c3643 100644
--- a/glib/demo/annots.c
+++ b/glib/demo/annots.c
@@ -36,6 +36,19 @@ enum {
N_COLUMNS
};
+enum {
+ SELECTED_TYPE_COLUMN,
+ SELECTED_LABEL_COLUMN,
+ SELECTED_N_COLUMNS
+};
+
+typedef enum {
+ MODE_NORMAL, /* Regular use as pointer in the page */
+ MODE_ADD, /* To add simple annotations */
+ MODE_EDIT, /* To move/edit an annotation */
+ MODE_DRAWING /* To add annotations that require mouse interactions */
+} ModeType;
+
typedef struct {
PopplerDocument *doc;
PopplerPage *page;
@@ -46,10 +59,18 @@ typedef struct {
GtkWidget *annot_view;
GtkWidget *timer_label;
GtkWidget *remove_button;
+ GtkWidget *type_selector;
+ GtkWidget *main_box;
gint num_page;
+ gint annot_type;
+ ModeType mode;
cairo_surface_t *surface;
+
+ GdkPoint start;
+ GdkPoint stop;
+ GdkCursorType cursor;
} PgdAnnotsDemo;
static void pgd_annots_viewer_queue_redraw (PgdAnnotsDemo *demo);
@@ -292,6 +313,45 @@ get_free_text_callout_line (PopplerAnnotFreeText *poppler_annot)
}
static void
+pgd_annots_update_cursor (PgdAnnotsDemo *demo,
+ GdkCursorType cursor_type)
+{
+ GdkCursor *cursor = NULL;
+
+ if (cursor_type == demo->cursor)
+ return;
+
+ if (cursor_type != GDK_LAST_CURSOR) {
+ cursor = gdk_cursor_new_for_display (gtk_widget_get_display (demo->main_box),
+ cursor_type);
+ }
+
+ demo->cursor = cursor_type;
+
+ gdk_window_set_cursor (gtk_widget_get_window (demo->main_box), cursor);
+ gdk_flush ();
+ if (cursor)
+ g_object_unref (cursor);
+}
+
+static void
+pgd_annots_start_add_annot (GtkWidget *button,
+ PgdAnnotsDemo *demo)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->type_selector), &iter);
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->type_selector));
+ gtk_tree_model_get (model, &iter,
+ SELECTED_TYPE_COLUMN, &(demo->annot_type),
+ -1);
+
+ demo->mode = MODE_ADD;
+ pgd_annots_update_cursor (demo, GDK_TCROSS);
+}
+
+static void
pgd_annots_remove_annot (GtkWidget *button,
PgdAnnotsDemo *demo)
{
@@ -566,6 +626,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;
@@ -604,42 +705,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);
@@ -736,113 +804,45 @@ pgd_annots_invisible_flag_toggled (GtkCellRendererToggle *renderer,
}
static void
-pgd_annots_add_annot (GtkWidget *button,
- PgdAnnotsDemo *demo)
+pgd_annots_add_annot (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);
+ PopplerRectangle rect;
+ PopplerAnnot *annot;
+ gdouble height;
- 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);
+ g_assert (demo->mode == MODE_ADD);
- 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);
+ poppler_page_get_size (demo->page, NULL, &height);
- gtk_box_pack_start (GTK_BOX (hbox), rect_hbox, FALSE, TRUE, 0);
- gtk_widget_show (rect_hbox);
+ rect.x1 = demo->start.x;
+ rect.y1 = height - demo->start.y;
+ rect.x2 = demo->stop.x;
+ rect.y2 = height - demo->stop.y;
- 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);
-
- 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));
+ switch (demo->annot_type) {
+ case POPPLER_ANNOT_TEXT:
+ annot = poppler_annot_text_new (demo->doc, &rect);
- 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);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
- g_object_unref (page);
+ poppler_page_add_annot (demo->page, annot);
+ pgd_annots_add_annot_to_model (demo, annot, rect);
+ g_object_unref (annot);
+}
- gtk_widget_destroy (dialog);
+static void
+pgd_annots_finish_add_annot (PgdAnnotsDemo *demo)
+{
+ g_assert (demo->mode == MODE_ADD || demo->mode == MODE_DRAWING);
+ demo->mode = MODE_NORMAL;
+ pgd_annots_update_cursor (demo, GDK_LAST_CURSOR);
pgd_annots_viewer_queue_redraw (demo);
- pgd_annots_get_annots (demo);
+
+ gtk_label_set_text (GTK_LABEL (demo->timer_label), NULL);
}
/* Render area */
@@ -918,6 +918,49 @@ 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->mode != MODE_ADD || event->button != 1)
+ return FALSE;
+
+ demo->start.x = event->x;
+ demo->start.y = event->y;
+ demo->stop = demo->start;
+
+ pgd_annots_add_annot (demo);
+ pgd_annots_viewer_queue_redraw (demo);
+ demo->mode = MODE_DRAWING;
+
+ return TRUE;
+}
+
+static gboolean
+pgd_annots_drawing_area_button_release (GtkWidget *area,
+ GdkEventButton *event,
+ PgdAnnotsDemo *demo)
+{
+ if (!demo->page || demo->mode != MODE_DRAWING || event->button != 1)
+ return FALSE;
+
+ pgd_annots_finish_add_annot (demo);
+
+ return TRUE;
+}
+
/* Main UI */
GtkWidget *
pgd_annots_create_widget (PopplerDocument *document)
@@ -932,12 +975,16 @@ pgd_annots_create_widget (PopplerDocument *document)
GtkTreeSelection *selection;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
+ GtkListStore *model;
+ GtkTreeIter iter;
gchar *str;
gint n_pages;
demo = g_new0 (PgdAnnotsDemo, 1);
demo->doc = g_object_ref (document);
+ demo->cursor = GDK_LAST_CURSOR;
+ demo->mode = MODE_NORMAL;
n_pages = poppler_document_get_n_pages (document);
@@ -971,14 +1018,34 @@ pgd_annots_create_widget (PopplerDocument *document)
gtk_box_pack_end (GTK_BOX (hbox), demo->remove_button, FALSE, FALSE, 6);
gtk_widget_show (demo->remove_button);
- button = gtk_button_new_with_label ("Add Annotation");
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+ button = gtk_button_new_from_stock (GTK_STOCK_ADD);
g_signal_connect (G_OBJECT (button), "clicked",
- G_CALLBACK (pgd_annots_add_annot),
- (gpointer) demo);
+ G_CALLBACK (pgd_annots_start_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, POPPLER_ANNOT_TEXT,
+ SELECTED_LABEL_COLUMN, "Text",
+ -1);
+ demo->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 (demo->type_selector), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (demo->type_selector), renderer,
+ "text", SELECTED_LABEL_COLUMN,
+ NULL);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (demo->type_selector), 0);
+ gtk_box_pack_end (GTK_BOX (hbox), demo->type_selector, FALSE, FALSE, 0);
+ gtk_widget_show (demo->type_selector);
+
gtk_widget_show (hbox);
demo->timer_label = gtk_label_new (NULL);
@@ -1096,6 +1163,15 @@ 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, "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)
@@ -1120,5 +1196,7 @@ pgd_annots_create_widget (PopplerDocument *document)
pgd_annots_viewer_queue_redraw (demo);
pgd_annots_get_annots (demo);
+ demo->main_box = vbox;
+
return vbox;
}
More information about the poppler
mailing list