Began to implement ZathuraDocument

This commit is contained in:
Moritz Lipp 2012-08-13 18:29:09 +02:00
parent 6de5978127
commit 5e7717b2c1
4 changed files with 271 additions and 75 deletions

View File

@ -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

215
document-widget.c Normal file
View File

@ -0,0 +1,215 @@
/* 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
}
}

48
document-widget.h Normal file
View File

@ -0,0 +1,48 @@
/* See LICENSE file for license and copyright information */
#ifndef DOCUMENT_WIDGET_H
#define DOCUMENT_WIDGET_H
#include <gtk/gtk.h>
#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

View File

@ -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);
}