[libgepub/widget-pagination] Controlling the page and number of pages in chapter
- From: Daniel Garcia Moreno <danigm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgepub/widget-pagination] Controlling the page and number of pages in chapter
- Date: Sun, 7 Aug 2016 10:54:50 +0000 (UTC)
commit 48b6f734cdb47df4916375b5075f7256ead4aef5
Author: Daniel Garcia Moreno <danigm wadobo com>
Date: Sun Aug 7 12:51:55 2016 +0200
Controlling the page and number of pages in chapter
I've added two new properties to the widget, the current page and the
number of pages in the chapter.
The number of pages is getted from javascript, because I'm paginating using
javascript and css.
libgepub/gepub-widget.c | 214 ++++++++++++++++++++++++++++++++++++----------
libgepub/gepub-widget.h | 5 +
tests/test-gepub.c | 46 ++++++++---
3 files changed, 206 insertions(+), 59 deletions(-)
---
diff --git a/libgepub/gepub-widget.c b/libgepub/gepub-widget.c
index 5d5a846..1d55f94 100644
--- a/libgepub/gepub-widget.c
+++ b/libgepub/gepub-widget.c
@@ -19,6 +19,7 @@
#include <config.h>
#include <gtk/gtk.h>
+#include <JavaScriptCore/JSValueRef.h>
#include "gepub-widget.h"
@@ -28,6 +29,7 @@ struct _GepubWidget {
GepubDoc *doc;
gboolean paginate;
gint page;
+ gint chapter_pages;
};
struct _GepubWidgetClass {
@@ -38,6 +40,8 @@ enum {
PROP_0,
PROP_DOC,
PROP_PAGINATE,
+ PROP_PAGE,
+ PROP_NPAGES,
NUM_PROPS
};
@@ -46,6 +50,86 @@ static GParamSpec *properties[NUM_PROPS] = { NULL, };
G_DEFINE_TYPE (GepubWidget, gepub_widget, WEBKIT_TYPE_WEB_VIEW)
static void
+pagination_initialize_finished (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ WebKitJavascriptResult *js_result;
+ JSValueRef value;
+ JSGlobalContextRef context;
+ GError *error = NULL;
+ GepubWidget *widget = GEPUB_WIDGET (user_data);
+
+ js_result = webkit_web_view_run_javascript_finish (WEBKIT_WEB_VIEW (object), result, &error);
+ if (!js_result) {
+ g_warning ("Error running javascript: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ context = webkit_javascript_result_get_global_context (js_result);
+ value = webkit_javascript_result_get_value (js_result);
+ if (JSValueIsNumber (context, value)) {
+ double n;
+
+ n = JSValueToNumber (context, value, NULL);
+ widget->chapter_pages = (int)n;
+ g_object_notify_by_pspec (G_OBJECT (widget), properties[PROP_NPAGES]);
+ } else {
+ g_warning ("Error running javascript: unexpected return value");
+ }
+ webkit_javascript_result_unref (js_result);
+}
+
+static void
+paginate_cb (WebKitWebView *web_view,
+ WebKitLoadEvent load_event,
+ gpointer user_data)
+{
+
+ GepubWidget *widget = GEPUB_WIDGET (web_view);
+
+ if (load_event == WEBKIT_LOAD_FINISHED) {
+ const gchar *script = "function initialize() { "
+ "var d = document.querySelector('body');"
+ "var ourH = window.innerHeight - 40; "
+ "var ourW = window.innerWidth - 20; "
+ "var fullH = d.offsetHeight; "
+ "var pageCount = Math.floor(fullH/ourH)+1;"
+ "var newW = pageCount * ourW; "
+ "d.style.height = ourH+'px';"
+ "d.style.width = newW+'px';"
+ "d.style.WebkitColumnCount = pageCount;"
+ "d.style.WebkitColumnGap = '20px';"
+ "d.style.overflow = 'hidden';"
+ "window.currentPage = 0; "
+ "return pageCount;"
+ "};"
+ "function next() { "
+ "var ourW = window.innerWidth - 10; "
+ "window.currentPage += 1; "
+ "window.scroll(ourW * window.currentPage, 0); "
+ "};"
+ "function prev() { "
+ "var ourW = window.innerWidth - 10; "
+ "window.currentPage -= 1; "
+ "window.scroll(ourW * window.currentPage, 0); "
+ "};"
+ "function nth(index) { "
+ "var ourW = window.innerWidth - 10; "
+ "window.currentPage = index; "
+ "window.scroll(ourW * window.currentPage, 0); "
+ "};"
+ "initialize();";
+
+ if (widget->paginate) {
+ webkit_web_view_run_javascript (web_view, "document.querySelector('body').style.margin =
'20px';", NULL, NULL, NULL);
+ webkit_web_view_run_javascript (web_view, script, NULL, pagination_initialize_finished,
(gpointer)widget);
+ }
+ }
+}
+
+static void
resource_callback (WebKitURISchemeRequest *request, gpointer user_data)
{
GInputStream *stream;
@@ -93,6 +177,9 @@ gepub_widget_set_property (GObject *object,
case PROP_PAGINATE:
gepub_widget_set_pagination (widget, g_value_get_boolean (value));
break;
+ case PROP_PAGE:
+ gepub_widget_set_page (widget, g_value_get_int (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -114,6 +201,12 @@ gepub_widget_get_property (GObject *object,
case PROP_PAGINATE:
g_value_set_boolean (value, widget->paginate);
break;
+ case PROP_PAGE:
+ g_value_set_int (value, gepub_widget_get_page (widget));
+ break;
+ case PROP_NPAGES:
+ g_value_set_int (value, gepub_widget_get_n_pages (widget));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -145,6 +238,7 @@ gepub_widget_constructed (GObject *object)
ctx = webkit_web_view_get_context (WEBKIT_WEB_VIEW (widget));
webkit_web_context_register_uri_scheme (ctx, "epub", resource_callback, widget, NULL);
+ g_signal_connect (widget, "load-changed", G_CALLBACK (paginate_cb), NULL);
}
static void
@@ -172,6 +266,20 @@ gepub_widget_class_init (GepubWidgetClass *klass)
FALSE,
G_PARAM_READWRITE);
+ properties[PROP_PAGE] =
+ g_param_spec_int ("page",
+ "Current page",
+ "Current page in the chapter",
+ -1, G_MAXINT, 0,
+ G_PARAM_READWRITE);
+
+ properties[PROP_NPAGES] =
+ g_param_spec_int ("chapter_pages",
+ "Current chapter pages",
+ "Current chapter number of pages",
+ -1, G_MAXINT, 0,
+ G_PARAM_READABLE);
+
g_object_class_install_properties (object_class, NUM_PROPS, properties);
}
@@ -200,48 +308,6 @@ gepub_widget_get_doc (GepubWidget *widget)
}
static void
-paginate_cb (WebKitWebView *web_view,
- WebKitLoadEvent load_event,
- gpointer user_data)
-{
-
- GepubWidget *widget = GEPUB_WIDGET (web_view);
-
- if (load_event == WEBKIT_LOAD_FINISHED) {
- const gchar *script = "function initialize() { "
- "var d = document.querySelector('body');"
- "var ourH = window.innerHeight - 40; "
- "var ourW = window.innerWidth - 20; "
- "var fullH = d.offsetHeight; "
- "var pageCount = Math.floor(fullH/ourH)+1;"
- "var newW = pageCount * ourW; "
- "d.style.height = ourH+'px';"
- "d.style.width = newW+'px';"
- "d.style.WebkitColumnCount = pageCount;"
- "d.style.WebkitColumnGap = '20px';"
- "d.style.overflow = 'hidden';"
- "window.currentPage = 0; "
- "};"
- "function next() { "
- "var ourW = window.innerWidth - 10; "
- "window.currentPage += 1; "
- "window.scroll(ourW * window.currentPage, 0); "
- "};"
- "function prev() { "
- "var ourW = window.innerWidth - 10; "
- "window.currentPage -= 1; "
- "window.scroll(ourW * window.currentPage, 0); "
- "};"
- "initialize();";
-
- if (widget->paginate) {
- webkit_web_view_run_javascript(web_view, "document.querySelector('body').style.margin =
'20px';", NULL, NULL, NULL);
- webkit_web_view_run_javascript(web_view, script, NULL, NULL, NULL);
- }
- }
-}
-
-static void
reload_current_chapter (GepubWidget *widget)
{
GBytes *current;
@@ -251,9 +317,6 @@ reload_current_chapter (GepubWidget *widget)
current,
gepub_doc_get_current_mime (widget->doc),
"UTF-8", NULL);
-
- g_signal_connect (widget, "load-changed", G_CALLBACK (paginate_cb), NULL);
-
g_bytes_unref (current);
}
@@ -313,7 +376,11 @@ gepub_widget_set_pagination (GepubWidget *widget,
void
gepub_widget_page_next (GepubWidget *widget)
{
- webkit_web_view_run_javascript(WEBKIT_WEB_VIEW (widget), "next();", NULL, NULL, NULL);
+ if (widget->page >= widget->chapter_pages)
+ return;
+
+ webkit_web_view_run_javascript (WEBKIT_WEB_VIEW (widget), "next();", NULL, NULL, NULL);
+ widget->page += 1;
}
/**
@@ -325,5 +392,58 @@ gepub_widget_page_next (GepubWidget *widget)
void
gepub_widget_page_prev (GepubWidget *widget)
{
- webkit_web_view_run_javascript(WEBKIT_WEB_VIEW (widget), "prev();", NULL, NULL, NULL);
+ if (widget->page <= 0)
+ return;
+
+ webkit_web_view_run_javascript (WEBKIT_WEB_VIEW (widget), "prev();", NULL, NULL, NULL);
+ widget->page -= 1;
+}
+
+/**
+ * gepub_widget_get_n_pages:
+ * @widget: a #GepubWidget
+ *
+ * Returns: the number of pages in the chapter
+ */
+int
+gepub_widget_get_n_pages (GepubWidget *widget)
+{
+ return widget->chapter_pages;
+}
+
+/**
+ * gepub_widget_get_page:
+ * @widget: a #GepubWidget
+ *
+ * Returns: the current page in the chapter
+ */
+int
+gepub_widget_get_page (GepubWidget *widget)
+{
+ return widget->page;
+}
+
+/**
+ * gepub_widget_set_page:
+ * @widget: a #GepubWidget
+ * @index: the new page index
+ *
+ * Sets the widget current page to @index.
+ */
+void
+gepub_widget_set_page (GepubWidget *widget, gint index)
+{
+ gchar *script;
+
+ if (index >= widget->chapter_pages)
+ return;
+
+ if (index < 0)
+ return;
+
+ script = g_strdup_printf ("nth(%d);", index);
+ webkit_web_view_run_javascript (WEBKIT_WEB_VIEW (widget), script, NULL, NULL, NULL);
+ widget->page = index;
+
+ g_free (script);
}
diff --git a/libgepub/gepub-widget.h b/libgepub/gepub-widget.h
index 5c4ce84..d825bd1 100644
--- a/libgepub/gepub-widget.h
+++ b/libgepub/gepub-widget.h
@@ -50,6 +50,11 @@ void gepub_widget_set_pagination (GepubWidget *wid
void gepub_widget_page_next (GepubWidget *widget);
void gepub_widget_page_prev (GepubWidget *widget);
+gint gepub_widget_get_n_pages (GepubWidget *widget);
+gint gepub_widget_get_page (GepubWidget *widget);
+void gepub_widget_set_page (GepubWidget *widget,
+ gint index);
+
G_END_DECLS
#endif /* __GEPUB_WIDGET_H__ */
diff --git a/tests/test-gepub.c b/tests/test-gepub.c
index 4aa5f29..ace6893 100644
--- a/tests/test-gepub.c
+++ b/tests/test-gepub.c
@@ -8,6 +8,7 @@ gchar *buf2 = NULL;
gchar *tmpbuf;
GtkTextBuffer *page_buffer;
+GtkWidget *PAGE_LABEL;
#define PTEST1(...) printf (__VA_ARGS__)
#define PTEST2(...) buf = g_strdup_printf (__VA_ARGS__);\
@@ -19,6 +20,14 @@ GtkTextBuffer *page_buffer;
#define TEST(f,arg...) PTEST ("\n### TESTING " #f " ###\n\n"); f (arg); PTEST ("\n\n");
+static void
+reload_current_chapter (GepubWidget *widget)
+{
+ gchar *txt = g_strdup_printf ("%d", gepub_widget_get_n_pages (widget));
+ gtk_label_set_text (GTK_LABEL (PAGE_LABEL), txt);
+ g_free (txt);
+}
+
void
update_text (GepubDoc *doc)
{
@@ -75,10 +84,6 @@ button_pressed (GtkButton *button, GepubWidget *widget)
gepub_doc_go_prev (doc);
} else if (!strcmp (gtk_button_get_label (button), "chapter >")) {
gepub_doc_go_next (doc);
- } else if (!strcmp (gtk_button_get_label (button), "< page")) {
- gepub_widget_page_prev (widget);
- } else if (!strcmp (gtk_button_get_label (button), "page >")) {
- gepub_widget_page_next (widget);
} else if (!strcmp (gtk_button_get_label (button), "paginated")) {
gboolean b = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
gepub_widget_set_pagination (widget, b);
@@ -88,6 +93,21 @@ button_pressed (GtkButton *button, GepubWidget *widget)
}
void
+spin_changed (GtkSpinButton *button, GepubWidget *widget)
+{
+ gint value = gtk_spin_button_get_value_as_int (button);
+ gint npages = gepub_widget_get_n_pages (widget);
+
+ printf ("PAGE VALUE: %d - %d\n", value, npages);
+ if (value >= gepub_widget_get_n_pages (widget)) {
+ gtk_spin_button_set_value (button, npages);
+ return;
+ }
+
+ gepub_widget_set_page (widget, value);
+}
+
+void
test_open (const char *path)
{
GepubArchive *a;
@@ -253,8 +273,7 @@ main (int argc, char **argv)
GtkWidget *b_next;
GtkWidget *b_prev;
- GtkWidget *b_next2;
- GtkWidget *b_prev2;
+ GtkWidget *spin_button;
GtkWidget *paginate;
@@ -303,10 +322,13 @@ main (int argc, char **argv)
b_next = gtk_button_new_with_label ("chapter >");
g_signal_connect (b_next, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget));
- b_prev2 = gtk_button_new_with_label ("< page");
- g_signal_connect (b_prev2, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget));
- b_next2 = gtk_button_new_with_label ("page >");
- g_signal_connect (b_next2, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget));
+ spin_button = gtk_spin_button_new_with_range (0, G_MAXINT, 1);
+ g_signal_connect (spin_button, "value-changed", (GCallback)spin_changed, GEPUB_WIDGET (widget));
+
+ PAGE_LABEL = gtk_label_new ("0");
+
+ g_signal_connect_swapped (widget, "notify",
+ G_CALLBACK (reload_current_chapter), widget);
paginate = gtk_check_button_new_with_label ("paginated");
g_signal_connect (paginate, "clicked", (GCallback)button_pressed, GEPUB_WIDGET (widget));
@@ -314,8 +336,8 @@ main (int argc, char **argv)
gtk_container_add (GTK_CONTAINER (hbox), b_prev);
gtk_container_add (GTK_CONTAINER (hbox), b_next);
- gtk_container_add (GTK_CONTAINER (hbox), b_prev2);
- gtk_container_add (GTK_CONTAINER (hbox), b_next2);
+ gtk_container_add (GTK_CONTAINER (hbox), spin_button);
+ gtk_container_add (GTK_CONTAINER (hbox), PAGE_LABEL);
gtk_container_add (GTK_CONTAINER (hbox), paginate);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]