mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-11-10 18:13:46 +01:00
216 lines
7.4 KiB
C
216 lines
7.4 KiB
C
|
/* See LICENSE file for license and copyright information */
|
||
|
|
||
|
#include <girara/utils.h>
|
||
|
#include <girara/settings.h>
|
||
|
#include <girara/datastructures.h>
|
||
|
#include <girara/session.h>
|
||
|
#include <string.h>
|
||
|
#include <glib/gi18n.h>
|
||
|
#include <math.h>
|
||
|
|
||
|
#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
|
||
|
}
|
||
|
}
|