[libgepub/wip/doublepage] starting to implement double page widget



commit a6169a8a85619e1c4b618be13e8b0637f4ca8c05
Author: Daniel GarcĂ­a Moreno <danigm wadobo com>
Date:   Tue May 23 14:33:54 2017 +0200

    starting to implement double page widget

 libgepub/Makefile.am           |   10 +-
 libgepub/gepub-double-widget.c |  337 ++++++++++++++++++++++++++++++++++++++++
 libgepub/gepub-double-widget.h |   75 +++++++++
 libgepub/gepub-widget.c        |   22 +++-
 libgepub/gepub-widget.h        |    1 +
 libgepub/gepub.h               |    1 +
 tests/double-page-epub.py      |   56 +++++++
 7 files changed, 497 insertions(+), 5 deletions(-)
---
diff --git a/libgepub/Makefile.am b/libgepub/Makefile.am
index 1ae6339..7a0b65a 100644
--- a/libgepub/Makefile.am
+++ b/libgepub/Makefile.am
@@ -4,10 +4,11 @@ NOINST_H_FILES = \
        gepub-utils.h
 
 INST_H_FILES = \
-       gepub-widget.h          \
-       gepub-archive.h         \
-       gepub-text-chunk.h      \
-       gepub-doc.h             \
+       gepub-widget.h                  \
+       gepub-double-widget.h   \
+       gepub-archive.h                 \
+       gepub-text-chunk.h              \
+       gepub-doc.h                             \
        gepub.h
 
 libgepubincludedir = $(includedir)/libgepub
@@ -15,6 +16,7 @@ libgepubinclude_HEADERS = $(INST_H_FILES)
 
 libgepub_la_SOURCES = \
        gepub-widget.c                  \
+       gepub-double-widget.c   \
        gepub-archive.c                 \
        gepub-text-chunk.c              \
        gepub-doc.c                             \
diff --git a/libgepub/gepub-double-widget.c b/libgepub/gepub-double-widget.c
new file mode 100644
index 0000000..5c28c21
--- /dev/null
+++ b/libgepub/gepub-double-widget.c
@@ -0,0 +1,337 @@
+/* GepubDoubleWidget
+ *
+ * Copyright (C) 2017 Daniel Garcia <danigm wadobo com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <JavaScriptCore/JSValueRef.h>
+#include <locale.h>
+
+#include "gepub-double-widget.h"
+
+struct _GepubDoubleWidget {
+    GtkBox parent;
+
+    GepubWidget *page1;
+    GepubWidget *page2;
+
+    GepubDoc *doc1;
+    GepubDoc *doc2;
+
+    gboolean setnext;
+};
+
+struct _GepubDoubleWidgetClass {
+    GtkBoxClass parent_class;
+};
+
+G_DEFINE_TYPE (GepubDoubleWidget, gepub_double_widget, GTK_TYPE_BOX)
+
+static void
+gepub_double_widget_finalize (GObject *object)
+{
+    GepubDoubleWidget *widget = GEPUB_DOUBLE_WIDGET (object);
+
+    if (widget->doc1) {
+        g_object_unref (G_OBJECT (widget->doc1));
+    }
+    if (widget->doc2) {
+        g_object_unref (G_OBJECT (widget->doc2));
+    }
+
+    G_OBJECT_CLASS (gepub_double_widget_parent_class)->finalize (object);
+}
+
+static gboolean
+page_next (gpointer data)
+{
+    GepubWidget *w = GEPUB_WIDGET (data);
+    gepub_widget_page_next (w);
+    return FALSE;
+}
+
+static gboolean
+page_prev (gpointer data)
+{
+    GepubWidget *w = GEPUB_WIDGET (data);
+    gepub_widget_page_prev (w);
+    return FALSE;
+}
+
+static void
+gepub_double_widget_init (GepubDoubleWidget *widget)
+{
+    widget->page1 = GEPUB_WIDGET (gepub_widget_new ());
+    widget->page2 = GEPUB_WIDGET (gepub_widget_new ());
+    widget->setnext = FALSE;
+
+    widget->doc1 = NULL;
+    widget->doc2 = NULL;
+
+    gtk_box_pack_start (GTK_BOX (widget), GTK_WIDGET (widget->page1), TRUE, TRUE, 1);
+    gtk_box_pack_start (GTK_BOX (widget), GTK_WIDGET (widget->page2), TRUE, TRUE, 1);
+}
+
+static void
+gepub_double_widget_class_init (GepubDoubleWidgetClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    object_class->finalize = gepub_double_widget_finalize;
+}
+
+/**
+ * gepub_double_widget_new:
+ *
+ * Returns: (transfer full): the new GepubDoubleWidget created
+ */
+GtkWidget *
+gepub_double_widget_new (void)
+{
+    GObject *self;
+
+    self = g_object_new (GEPUB_TYPE_DOUBLE_WIDGET,
+                         "orientation", GTK_ORIENTATION_HORIZONTAL,
+                         NULL);
+
+    return GTK_WIDGET (self);
+}
+
+/**
+ * gepub_double_widget_open:
+ * @widget: a #GepubDoubleWidget
+ * @path: The full path to a epub document
+ *
+ * loads the epub by path
+ */
+void
+gepub_double_widget_open (GepubDoubleWidget *widget,
+                          gchar             *path)
+{
+    g_return_if_fail (GEPUB_IS_DOUBLE_WIDGET (widget));
+
+    widget->doc1 = gepub_doc_new (path);
+    widget->doc2 = gepub_doc_new (path);
+
+    gepub_widget_set_doc (widget->page1, widget->doc1);
+    gepub_widget_set_doc (widget->page2, widget->doc2);
+
+    widget->setnext = TRUE;
+    gepub_widget_set_pagination (widget->page1, TRUE);
+    gepub_widget_set_pagination (widget->page2, TRUE);
+
+    // TODO: don't use timeout, call this on ready
+    g_timeout_add(250, page_next, widget->page2);
+}
+
+/**
+ * gepub_double_widget_get_n_chapters:
+ * @widget: a #GepubDoubleWidget
+ *
+ * Returns: the number of chapters in the document
+ */
+gint
+gepub_double_widget_get_n_chapters (GepubDoubleWidget *widget)
+{
+    return gepub_widget_get_n_chapters (widget->page1);
+}
+
+/**
+ * gepub_double_widget_get_chapter:
+ * @widget: a #GepubDoubleWidget
+ *
+ * Returns: the current chapter in the document
+ */
+gint
+gepub_double_widget_get_chapter (GepubDoubleWidget *widget)
+{
+    return gepub_widget_get_chapter (widget->page1);
+}
+
+/**
+ * gepub_double_widget_get_chapter_length:
+ * @widget: a #GepubDoubleWidget
+ *
+ * Returns: the current chapter length
+ */
+gint
+gepub_double_widget_get_chapter_length (GepubDoubleWidget *widget)
+{
+    return gepub_widget_get_chapter_length (widget->page1);
+}
+
+/**
+ * gepub_double_widget_set_chapter:
+ * @widget: a #GepubDoubleWidget
+ * @index: the new chapter
+ *
+ * Sets the current chapter in the doc
+ */
+void
+gepub_double_widget_set_chapter (GepubDoubleWidget *widget,
+                                 gint               index)
+{
+    widget->setnext = TRUE;
+    gepub_widget_set_chapter (widget->page1, index);
+    gepub_widget_set_chapter (widget->page2, index);
+}
+
+/**
+ * gepub_double_widget_page_next:
+ * @widget: a #GepubDoubleWidget
+ *
+ * Returns: TRUE on success, FALSE if there's no next page
+ */
+gboolean
+gepub_double_widget_page_next (GepubDoubleWidget *widget)
+{
+    gepub_widget_page_next (widget->page1);
+    // TODO: don't use timeout, call this on ready
+    g_timeout_add(250, page_next, widget->page1);
+    gepub_widget_page_next (widget->page2);
+    g_timeout_add(250, page_next, widget->page2);
+    return TRUE;
+}
+
+/**
+ * gepub_double_widget_page_prev:
+ * @widget: a #GepubDoubleWidget
+ *
+ * Returns: TRUE on success, FALSE if there's no next page
+ */
+gboolean
+gepub_double_widget_page_prev (GepubDoubleWidget *widget)
+{
+    gepub_widget_page_prev (widget->page1);
+    // TODO: don't use timeout, call this on ready
+    g_timeout_add(250, page_prev, widget->page1);
+    gepub_widget_page_prev (widget->page2);
+    g_timeout_add(250, page_prev, widget->page2);
+    return TRUE;
+}
+
+/**
+ * gepub_double_widget_get_pos:
+ * @widget: a #GepubDoubleWidget
+ *
+ * Returns: the current position in the chapter
+ */
+gfloat
+gepub_double_widget_get_pos (GepubDoubleWidget *widget)
+{
+    return gepub_widget_get_pos (widget->page1);
+}
+
+/**
+ * gepub_double_widget_set_pos:
+ * @widget: a #GepubDoubleWidget
+ * @index: the new pos
+ *
+ * Sets the current position in the chapter
+ */
+void
+gepub_double_widget_set_pos (GepubDoubleWidget *widget,
+                             gfloat             index)
+{
+    gepub_widget_set_pos (widget->page1, index);
+    gepub_widget_set_pos (widget->page2, index);
+    gepub_widget_page_next (widget->page2);
+}
+
+
+/**
+ * gepub_double_widget_set_margin:
+ * @widget: a #GepubDoubleWidget
+ * @margin: the margin in pixels
+ *
+ * Sets the widget left and right margin
+ */
+void
+gepub_double_widget_set_margin (GepubDoubleWidget *widget,
+                                gint               margin)
+{
+    gepub_widget_set_margin (widget->page1, margin);
+    gepub_widget_set_margin (widget->page2, margin);
+}
+
+/**
+ * gepub_double_widget_get_margin:
+ * @widget: a #GepubDoubleWidget
+ *
+ * Gets the widget left and right margin
+ */
+gint
+gepub_double_widget_get_margin (GepubDoubleWidget *widget)
+{
+    return gepub_widget_get_margin (widget->page1);
+}
+
+/**
+ * gepub_double_widget_get_fontsize:
+ * @widget: a #GepubDoubleWidget
+ *
+ * Gets the widget custom font size in pt, if 0, it's not set
+ */
+gint
+gepub_double_widget_get_fontsize (GepubDoubleWidget *widget)
+{
+    return gepub_widget_get_fontsize (widget->page1);
+}
+
+/**
+ * gepub_double_widget_set_fontsize:
+ * @widget: a #GepubDouble_Widget
+ * @size: the custom font size in pt
+ *
+ * Sets the widget custom font size, use 0 to show book's styles
+ */
+void
+gepub_double_widget_set_fontsize (GepubDoubleWidget *widget,
+                                  gint               size)
+{
+    gepub_widget_set_fontsize (widget->page1, size);
+    gepub_widget_set_fontsize (widget->page2, size);
+}
+
+/**
+ * gepub_double_widget_get_lineheight:
+ * @widget: a #GepubDoubleWidget
+ *
+ * Gets the widget custom line height, if 0, it's not set
+ */
+gfloat
+gepub_double_widget_get_lineheight (GepubDoubleWidget *widget)
+{
+    return gepub_widget_get_lineheight (widget->page1);
+}
+
+/**
+ * gepub_double_widget_set_lineheight:
+ * @widget: a #GepubDoubleWidget
+ * @size: the custom line height
+ *
+ * Sets the widget custom line height, the real size will be this
+ * number multiplied by the font size.
+ * Use 0 to show book's styles
+ */
+void
+gepub_double_widget_set_lineheight (GepubDoubleWidget *widget,
+                                    gfloat             size)
+{
+    gepub_widget_set_lineheight (widget->page1, size);
+    gepub_widget_set_lineheight (widget->page2, size);
+}
diff --git a/libgepub/gepub-double-widget.h b/libgepub/gepub-double-widget.h
new file mode 100644
index 0000000..8af7f5f
--- /dev/null
+++ b/libgepub/gepub-double-widget.h
@@ -0,0 +1,75 @@
+/* GepubDoubleWidget
+ *
+ * Copyright (C) 2017 Daniel Garcia <danigm wadobo com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef __GEPUB_DOUBLE_WIDGET_H__
+#define __GEPUB_DOUBLE_WIDGET_H__
+
+#include <webkit2/webkit2.h>
+#include <glib-object.h>
+#include <glib.h>
+
+#include "gepub-widget.h"
+
+G_BEGIN_DECLS
+
+#define GEPUB_TYPE_DOUBLE_WIDGET           (gepub_double_widget_get_type ())
+#define GEPUB_DOUBLE_WIDGET(obj)           (G_TYPE_CHECK_INSTANCE_CAST (obj, GEPUB_TYPE_DOUBLE_WIDGET, 
GepubDoubleWidget))
+#define GEPUB_DOUBLE_WIDGET_CLASS(cls)     (G_TYPE_CHECK_CLASS_CAST (cls, GEPUB_TYPE_DOUBLE_WIDGET, 
GepubDoubleWidgetClass))
+#define GEPUB_IS_DOUBLE_WIDGET(obj)        (G_TYPE_CHECK_INSTANCE_TYPE (obj, GEPUB_TYPE_DOUBLE_WIDGET))
+#define GEPUB_IS_DOUBLE_WIDGET_CLASS(obj)  (G_TYPE_CHECK_CLASS_TYPE (obj, GEPUB_TYPE_DOUBLE_WIDGET))
+#define GEPUB_DOUBLE_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GEPUB_TYPE_DOUBLE_WIDGET, 
GepubDoubleWidgetClass))
+
+typedef struct _GepubDoubleWidget      GepubDoubleWidget;
+typedef struct _GepubDoubleWidgetClass GepubDoubleWidgetClass;
+
+GType             gepub_double_widget_get_type                        (void) G_GNUC_CONST;
+
+GtkWidget        *gepub_double_widget_new                             (void);
+
+void              gepub_double_widget_open                            (GepubDoubleWidget *widget,
+                                                                       gchar *path);
+
+gint              gepub_double_widget_get_n_chapters                  (GepubDoubleWidget *widget);
+gint              gepub_double_widget_get_chapter                     (GepubDoubleWidget *widget);
+gint              gepub_double_widget_get_chapter_length              (GepubDoubleWidget *widget);
+void              gepub_double_widget_set_chapter                     (GepubDoubleWidget *widget,
+                                                                       gint         index);
+
+gfloat            gepub_double_widget_get_pos                         (GepubDoubleWidget *widget);
+void              gepub_double_widget_set_pos                         (GepubDoubleWidget *widget,
+                                                                       gfloat       index);
+gboolean          gepub_double_widget_page_next                       (GepubDoubleWidget *widget);
+gboolean          gepub_double_widget_page_prev                       (GepubDoubleWidget *widget);
+
+gint              gepub_double_widget_get_margin                      (GepubDoubleWidget *widget);
+void              gepub_double_widget_set_margin                      (GepubDoubleWidget *widget,
+                                                                       gint         margin);
+
+gint              gepub_double_widget_get_fontsize                    (GepubDoubleWidget *widget);
+void              gepub_double_widget_set_fontsize                    (GepubDoubleWidget *widget,
+                                                                       gint         size);
+
+gfloat            gepub_double_widget_get_lineheight                  (GepubDoubleWidget *widget);
+void              gepub_double_widget_set_lineheight                  (GepubDoubleWidget *widget,
+                                                                       gfloat       size);
+
+G_END_DECLS
+
+#endif /* __GEPUB_DOUBLE_WIDGET_H__ */
+
diff --git a/libgepub/gepub-widget.c b/libgepub/gepub-widget.c
index 05cb06c..e9419f0 100644
--- a/libgepub/gepub-widget.c
+++ b/libgepub/gepub-widget.c
@@ -121,6 +121,8 @@ pagination_initialize_finished (GObject      *object,
         g_warning ("Error running javascript: unexpected return value");
     }
     webkit_javascript_result_unref (js_result);
+
+    g_signal_emit_by_name (widget, "pagination-finished");
 }
 
 static void
@@ -399,6 +401,12 @@ gepub_widget_class_init (GepubWidgetClass *klass)
                             G_PARAM_READWRITE);
 
     g_object_class_install_properties (object_class, NUM_PROPS, properties);
+
+    g_signal_newv ("pagination-finished",
+                   G_TYPE_FROM_CLASS (object_class),
+                   G_SIGNAL_RUN_LAST,
+                   NULL, NULL, NULL, NULL, G_TYPE_NONE,
+                   0, NULL);
 }
 
 /**
@@ -494,6 +502,18 @@ gepub_widget_set_pagination (GepubWidget *widget,
 }
 
 /**
+ * gepub_widget_get_pagination:
+ * @widget: a #GepubWidget
+ *
+ * Return the pagination state
+ */
+gboolean
+gepub_widget_get_pagination (GepubWidget *widget)
+{
+    return widget->paginate;
+}
+
+/**
  * gepub_widget_get_n_chapters:
  * @widget: a #GepubWidget
  *
@@ -544,7 +564,7 @@ gepub_widget_set_chapter (GepubWidget *widget,
                           gint         index)
 {
     g_return_if_fail (GEPUB_IS_DOC (widget->doc));
-    return gepub_doc_set_page (widget->doc, index);
+    gepub_doc_set_page (widget->doc, index);
 }
 
 /**
diff --git a/libgepub/gepub-widget.h b/libgepub/gepub-widget.h
index 9c141a8..c07ba25 100644
--- a/libgepub/gepub-widget.h
+++ b/libgepub/gepub-widget.h
@@ -47,6 +47,7 @@ void              gepub_widget_set_doc                         (GepubWidget *wid
                                                                 GepubDoc    *doc);
 
 void              gepub_widget_set_pagination                  (GepubWidget *widget, gboolean p);
+gboolean          gepub_widget_get_pagination                  (GepubWidget *widget);
 
 gint              gepub_widget_get_n_chapters                  (GepubWidget *widget);
 gint              gepub_widget_get_chapter                     (GepubWidget *widget);
diff --git a/libgepub/gepub.h b/libgepub/gepub.h
index a8f7fd2..0d64f84 100644
--- a/libgepub/gepub.h
+++ b/libgepub/gepub.h
@@ -5,5 +5,6 @@
 #include "gepub-text-chunk.h"
 #include "gepub-doc.h"
 #include "gepub-widget.h"
+#include "gepub-double-widget.h"
 
 #endif
diff --git a/tests/double-page-epub.py b/tests/double-page-epub.py
new file mode 100755
index 0000000..f32bb61
--- /dev/null
+++ b/tests/double-page-epub.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python3
+
+import sys
+
+import gi
+gi.require_version('Gtk', '3.0')
+gi.require_version('Gepub', '0.4')
+
+from gi.repository import Gtk
+from gi.repository import Gepub
+
+
+class MyWindow(Gtk.Window):
+
+    def __init__(self, book):
+        Gtk.Window.__init__(self)
+
+        self.set_default_size(1000, 600)
+
+        self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
+        box2 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
+
+        self.w = Gepub.DoubleWidget.new()
+        self.w.open(book)
+
+        self.p = Gtk.Button("prev")
+        self.n = Gtk.Button("next")
+        self.p.connect('clicked', self.prevcb)
+        self.n.connect('clicked', self.nextcb)
+
+        box2.add(self.p)
+        box2.add(self.n)
+
+        self.box.add(box2)
+        self.box.pack_start(self.w, True, True, 0)
+
+        self.add(self.box)
+
+    def prevcb(self, btn):
+        self.w.page_prev()
+
+    def nextcb(self, btn):
+        self.w.page_next()
+
+
+if len(sys.argv) != 2:
+    print("we need an epub as argument to work")
+    sys.exit(0)
+book = sys.argv[1]
+
+
+win = MyWindow(book)
+win.connect("delete-event", Gtk.main_quit)
+win.show_all()
+
+Gtk.main()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]