diff --git a/config.c b/config.c index 99443b3..38726d3 100644 --- a/config.c +++ b/config.c @@ -51,16 +51,7 @@ cb_page_padding_changed(girara_session_t* session, const char* UNUSED(name), g_return_if_fail(session->global.data != NULL); zathura_t* zathura = session->global.data; - int val = *(int*) value; - if (GTK_IS_TABLE(zathura->ui.page_widget) == TRUE) { -#if (GTK_MAJOR_VERSION == 3) - gtk_grid_set_row_spacing(GTK_GRID(zathura->ui.page_widget), val); - gtk_grid_set_column_spacing(GTK_GRID(zathura->ui.page_widget), val); -#else - gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_widget), val); - gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_widget), val); -#endif - } + g_object_set(G_OBJECT(zathura->ui.page_widget), "page-padding", *(int*) value, NULL); } static void diff --git a/document-widget.c b/document-widget.c new file mode 100644 index 0000000..e2b26b7 --- /dev/null +++ b/document-widget.c @@ -0,0 +1,215 @@ +/* See LICENSE file for license and copyright information */ + +#include +#include +#include +#include +#include +#include +#include + +#include "links.h" +#include "document-widget.h" +#include "render.h" +#include "utils.h" +#include "shortcuts.h" +#include "synctex.h" + +G_DEFINE_TYPE(ZathuraDocument, zathura_document_widget, GTK_TYPE_BIN) + +typedef struct zathura_document_widget_private_s { + zathura_document_t* document; /**< Document object */ + zathura_t* zathura; /**< Zathura object */ + bool continuous_mode; /**< Continuous mode */ + int page_padding; /**< Page padding */ + int pages_per_row; /** Pages per row */ + int first_page_column; /** First page column */ + GtkWidget* view; + GStaticMutex lock; /**< Lock */ +} zathura_document_widget_private_t; + +#define ZATHURA_DOCUMENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((obj), ZATHURA_TYPE_DOCUMENT, zathura_document_widget_private_t)) + +static void zathura_document_widget_finalize(GObject* object); +static void zathura_document_widget_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec); +static void zathura_document_widget_size_allocate(GtkWidget* widget, GdkRectangle* allocation); +static void zathura_document_widget_update_page_padding(zathura_document_widget_private_t* priv); +static void zathura_document_widget_update_mode(zathura_document_widget_private_t* priv); + +static void +remove_page_from_table(GtkWidget* page, gpointer permanent) +{ + if (permanent == false) { + g_object_ref(G_OBJECT(page)); + } + + gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(page)), page); +} + +enum properties_e +{ + PROP_0, + PROP_DOCUMENT, + PROP_ZATHURA, + PROP_CONTINUOUS_MODE, + PROP_PAGES_PER_ROW, + PROP_FIRST_PAGE_COLUMN, + PROP_PAGE_PADDING +}; + +static void +zathura_document_widget_class_init(ZathuraDocumentClass* class) +{ + /* add private members */ + g_type_class_add_private(class, sizeof(zathura_document_widget_private_t)); + + /* overwrite methods */ + GtkWidgetClass* widget_class = GTK_WIDGET_CLASS(class); + widget_class->size_allocate = zathura_document_widget_size_allocate; + + GObjectClass* object_class = G_OBJECT_CLASS(class); + object_class->finalize = zathura_document_widget_finalize; + object_class->set_property = zathura_document_widget_set_property; + + /* add properties */ + g_object_class_install_property(object_class, PROP_ZATHURA, + g_param_spec_pointer("zathura", "zathura", "the zathura instance", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(object_class, PROP_DOCUMENT, + g_param_spec_pointer("document", "document", "the document_to_display", G_PARAM_WRITABLE)); + g_object_class_install_property(object_class, PROP_CONTINUOUS_MODE, + g_param_spec_boolean("continuous-mode", "continuous-mode", "Set wether to enable or disable continuous mode", FALSE, G_PARAM_WRITABLE)); + g_object_class_install_property(object_class, PROP_PAGE_PADDING, + g_param_spec_int("page-padding", "page-padding", "Padding between the pages", 0, INT_MAX, 0, G_PARAM_WRITABLE)); + g_object_class_install_property(object_class, PROP_PAGES_PER_ROW, + g_param_spec_int("pages-per-row", "pages-per-row", "Pages per row", 0, INT_MAX, 1, G_PARAM_WRITABLE)); + g_object_class_install_property(object_class, PROP_FIRST_PAGE_COLUMN, + g_param_spec_int("first-page-column", "first-page-column", "First page column", 0, INT_MAX, 1, G_PARAM_WRITABLE)); +} + +static void +zathura_document_widget_init(ZathuraDocument* widget) +{ + zathura_document_widget_private_t* priv = ZATHURA_DOCUMENT_GET_PRIVATE(widget); + priv->zathura = NULL; + priv->document = NULL; + priv->pages_per_row = 1; + priv->first_page_column = 1; + +#if (GTK_MAJOR_VERSION == 3) + priv->view = gtk_grid_new(); +#else + priv->view = gtk_table_new(0, 0, TRUE); +#endif + + g_static_mutex_init(&(priv->lock)); +} + +GtkWidget* +zathura_document_widget_new(zathura_t* zathura) +{ + g_return_val_if_fail(zathura != NULL, NULL); + + return g_object_new(ZATHURA_TYPE_DOCUMENT, "zathura", zathura, NULL); +} + +static void +zathura_document_widget_size_allocate(GtkWidget* widget, GdkRectangle* allocation) +{ + GTK_WIDGET_CLASS(zathura_document_widget_parent_class)->size_allocate(widget, allocation); +} + +static void +zathura_document_widget_finalize(GObject* object) +{ + ZathuraDocument* widget = ZATHURA_DOCUMENT(object); + zathura_document_widget_private_t* priv = ZATHURA_DOCUMENT_GET_PRIVATE(widget); + + g_static_mutex_free(&(priv->lock)); + + G_OBJECT_CLASS(zathura_document_widget_parent_class)->finalize(object); +} + +static void +zathura_document_widget_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) +{ + ZathuraDocument* document = ZATHURA_DOCUMENT(object); + zathura_document_widget_private_t* priv = ZATHURA_DOCUMENT_GET_PRIVATE(document); + + switch (prop_id) { + case PROP_DOCUMENT: + priv->document = g_value_get_pointer(value); + break; + case PROP_ZATHURA: + priv->zathura = g_value_get_pointer(value); + break; + case PROP_CONTINUOUS_MODE: + priv->continuous_mode = g_value_get_boolean(value); + break; + case PROP_PAGES_PER_ROW: + priv->pages_per_row = g_value_get_int(value); + zathura_document_widget_update_mode(priv); + break; + case PROP_PAGE_PADDING: + priv->page_padding = g_value_get_int(value); + zathura_document_widget_update_page_padding(priv); + break; + case PROP_FIRST_PAGE_COLUMN: + priv->first_page_column = g_value_get_int(value); + zathura_document_widget_update_mode(priv); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + +static void +zathura_document_widget_update_page_padding(zathura_document_widget_private_t* priv) +{ +#if (GTK_MAJOR_VERSION == 3) + gtk_grid_set_row_spacing(GTK_GRID(priv->view), priv->page_padding); + gtk_grid_set_column_spacing(GTK_GRID(priv->view), priv->page_padding); +#else + gtk_table_set_row_spacings(GTK_TABLE(priv->view), priv->page_padding); + gtk_table_set_col_spacings(GTK_TABLE(priv->view), priv->page_padding); +#endif +} + +static void +zathura_document_widget_update_mode(zathura_document_widget_private_t* priv) +{ + /* show at least one page */ + if (priv->pages_per_row < 1) { + priv->pages_per_row = 1; + } + + /* ensure: 0 < first_page_column <= pages_per_row */ + if (priv->first_page_column < 1) { + priv->first_page_column = 1; + } + + if (priv->first_page_column > priv->pages_per_row) { + priv->first_page_column = ((priv->first_page_column - 1) % priv->pages_per_row) + 1; + } + + gtk_container_foreach(GTK_CONTAINER(priv->view), remove_page_from_table, (gpointer)0); + + unsigned int number_of_pages = zathura_document_get_number_of_pages(priv->document); +#if (GTK_MAJOR_VERSION == 3) +#else + gtk_table_resize(GTK_TABLE(priv->view), ceil((number_of_pages + priv->first_page_column - 1) / priv->pages_per_row), priv->pages_per_row); +#endif + + for (unsigned int i = 0; i < number_of_pages; i++) { + int x = (i + priv->first_page_column - 1) % priv->pages_per_row; + int y = (i + priv->first_page_column - 1) / priv->pages_per_row; + + zathura_page_t* page = zathura_document_get_page(priv->document, i); + GtkWidget* page_widget = zathura_page_get_widget(priv->zathura, page); +#if (GTK_MAJOR_VERSION == 3) + gtk_grid_attach(GTK_GRID(priv->view), page_widget, x, y, 1, 1); +#else + gtk_table_attach(GTK_TABLE(priv->view), page_widget, x, x + 1, y, y + 1, GTK_SHRINK, GTK_SHRINK, 0, 0); +#endif + } +} diff --git a/document-widget.h b/document-widget.h new file mode 100644 index 0000000..0d14172 --- /dev/null +++ b/document-widget.h @@ -0,0 +1,48 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef DOCUMENT_WIDGET_H +#define DOCUMENT_WIDGET_H + +#include +#include "document.h" + +typedef struct zathura_document_widget_s ZathuraDocument; +typedef struct zathura_document_widget_class_s ZathuraDocumentClass; + +struct zathura_document_widget_s +{ + GtkBin parent; +}; + +struct zathura_document_widget_class_s +{ + GtkBinClass parent_class; +}; + +#define ZATHURA_TYPE_DOCUMENT \ + (zathura_document_widget_get_type ()) +#define ZATHURA_DOCUMENT(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), ZATHURA_TYPE_DOCUMENT, ZathuraDocument)) +#define ZATHURA_DOCUMENT_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_CAST ((obj), ZATHURA_TYPE_DOCUMENT, ZathuraDocumentClass)) +#define ZATHURA_IS_DOCUMENT(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ZATHURA_TYPE_DOCUMENT)) +#define ZATHURA_IS_DOCUMENT_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE ((obj), ZATHURA_TYPE_DOCUMENT)) +#define ZATHURA_DOCUMENT_GET_CLASS \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), ZATHURA_TYPE_DOCUMENT, ZathuraDocumentClass)) + +/** + * Returns the type of the document view widget. + * @return the type + */ +GType zathura_document_widget_get_type(void); +/** + * Create a page view widget. + * @param zathura the zathura instance + * @param page the page to be displayed + * @return a page view widget + */ +GtkWidget* zathura_document_widget_new(zathura_t* zathura); + +#endif // DOCUMENT_WIDGET_H diff --git a/zathura.c b/zathura.c index 1ab8318..9d8892a 100644 --- a/zathura.c +++ b/zathura.c @@ -29,6 +29,7 @@ #include "marks.h" #include "render.h" #include "page.h" +#include "document-widget.h" #include "page-widget.h" #include "plugin.h" @@ -134,13 +135,7 @@ zathura_init(zathura_t* zathura) zathura->ui.session->events.unknown_command = cb_unknown_command; /* page view */ -#if (GTK_MAJOR_VERSION == 3) - zathura->ui.page_widget = gtk_grid_new(); - gtk_grid_set_row_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); - gtk_grid_set_column_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); -#else - zathura->ui.page_widget = gtk_table_new(0, 0, TRUE); -#endif + zathura->ui.page_widget = zathura_document_widget_new(zathura); if (zathura->ui.page_widget == NULL) { goto error_free; } @@ -194,14 +189,7 @@ zathura_init(zathura_t* zathura) /* set page padding */ int page_padding = 1; girara_setting_get(zathura->ui.session, "page-padding", &page_padding); - -#if (GTK_MAJOR_VERSION == 3) - gtk_grid_set_row_spacing(GTK_GRID(zathura->ui.page_widget), page_padding); - gtk_grid_set_column_spacing(GTK_GRID(zathura->ui.page_widget), page_padding); -#else - gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding); - gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding); -#endif + g_object_set(G_OBJECT(zathura->ui.page_widget), "page-padding", page_padding, NULL); /* database */ char* database = NULL; @@ -641,6 +629,8 @@ document_open(zathura_t* zathura, const char* path, const char* password) girara_setting_set(zathura->ui.session, "first-page-column", &first_page_column); page_widget_set_mode(zathura, pages_per_row, first_page_column); + g_object_set(G_OBJECT(zathura->ui.page_widget), "document", document, NULL); + girara_set_view(zathura->ui.session, zathura->ui.page_widget_alignment); /* threads */ @@ -734,16 +724,6 @@ document_save(zathura_t* zathura, const char* path, bool overwrite) return (error == ZATHURA_ERROR_OK) ? true : false; } -static void -remove_page_from_table(GtkWidget* page, gpointer permanent) -{ - if (permanent == false) { - g_object_ref(G_OBJECT(page)); - } - - gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(page)), page); -} - bool document_close(zathura_t* zathura, bool keep_monitor) { @@ -809,7 +789,6 @@ document_close(zathura_t* zathura, bool keep_monitor) zathura->sync.render_thread = NULL; /* remove widgets */ - gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_widget), remove_page_from_table, (gpointer) 1); for (unsigned int i = 0; i < zathura_document_get_number_of_pages(zathura->document); i++) { g_object_unref(zathura->pages[i]); } @@ -921,45 +900,8 @@ statusbar_page_number_update(zathura_t* zathura) void page_widget_set_mode(zathura_t* zathura, unsigned int pages_per_row, unsigned int first_page_column) { - /* show at least one page */ - if (pages_per_row == 0) { - pages_per_row = 1; - } - - /* ensure: 0 < first_page_column <= pages_per_row */ - if (first_page_column < 1) { - first_page_column = 1; - } - - if (first_page_column > pages_per_row) { - first_page_column = ((first_page_column - 1) % pages_per_row) + 1; - } - - if (zathura->document == NULL) { - return; - } - - gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_widget), remove_page_from_table, (gpointer)0); - - unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); -#if (GTK_MAJOR_VERSION == 3) -#else - gtk_table_resize(GTK_TABLE(zathura->ui.page_widget), ceil((number_of_pages + first_page_column - 1) / pages_per_row), pages_per_row); -#endif - - for (unsigned int i = 0; i < number_of_pages; i++) { - int x = (i + first_page_column - 1) % pages_per_row; - int y = (i + first_page_column - 1) / pages_per_row; - - zathura_page_t* page = zathura_document_get_page(zathura->document, i); - GtkWidget* page_widget = zathura_page_get_widget(zathura, page); -#if (GTK_MAJOR_VERSION == 3) - gtk_grid_attach(GTK_GRID(zathura->ui.page_widget), page_widget, x, y, 1, 1); -#else - gtk_table_attach(GTK_TABLE(zathura->ui.page_widget), page_widget, x, x + 1, y, y + 1, GTK_SHRINK, GTK_SHRINK, 0, 0); -#endif - } - + g_object_set(G_OBJECT(zathura->ui.page_widget), "pages-per-row", + pages_per_row, "first-page-column", first_page_column, NULL); gtk_widget_show_all(zathura->ui.page_widget); }