mirror of
https://git.pwmt.org/pwmt/zathura.git
synced 2024-12-27 14:06:00 +01:00
Add selection api, data, drawing functions
This commit is contained in:
parent
9930e031c5
commit
a3029ddff6
4 changed files with 116 additions and 9 deletions
|
@ -7,6 +7,7 @@
|
|||
#include <string.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "links.h"
|
||||
#include "page-widget.h"
|
||||
|
@ -15,6 +16,7 @@
|
|||
#include "utils.h"
|
||||
#include "shortcuts.h"
|
||||
#include "zathura.h"
|
||||
#include "zathura/document.h"
|
||||
|
||||
typedef struct zathura_page_widget_private_s {
|
||||
zathura_page_t* page; /**< Page object */
|
||||
|
@ -38,6 +40,12 @@ typedef struct zathura_page_widget_private_s {
|
|||
gboolean draw; /**< Draw search results */
|
||||
} search;
|
||||
|
||||
struct {
|
||||
girara_list_t *list; /**< List of selection rectangles that should be drawn */
|
||||
zathura_rectangle_t bounds; /** Bounds of highlighted selection */
|
||||
gboolean draw; /** Used to clear previous selection */
|
||||
} selection;
|
||||
|
||||
struct {
|
||||
girara_list_t* list; /**< List of images on the page */
|
||||
gboolean retrieved; /**< True if we already tried to retrieve the list of images */
|
||||
|
@ -617,14 +625,25 @@ zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo)
|
|||
++idx;
|
||||
);
|
||||
}
|
||||
/* draw selection */
|
||||
if (priv->mouse.selection.y2 != -1 && priv->mouse.selection.x2 != -1) {
|
||||
if (priv->selection.list != NULL && priv->selection.draw == true) {
|
||||
int i = 0;
|
||||
const GdkRGBA color = priv->zathura->ui.colors.highlight_color;
|
||||
cairo_set_source_rgba(cairo, color.red, color.green, color.blue, transparency);
|
||||
cairo_rectangle(cairo, priv->mouse.selection.x1, priv->mouse.selection.y1,
|
||||
(priv->mouse.selection.x2 - priv->mouse.selection.x1), (priv->mouse.selection.y2 - priv->mouse.selection.y1));
|
||||
cairo_fill(cairo);
|
||||
GIRARA_LIST_FOREACH_BODY(priv->selection.list, zathura_rectangle_t*, rect,
|
||||
zathura_rectangle_t rectangle = recalc_rectangle(priv->page, *rect);
|
||||
cairo_rectangle(cairo, rectangle.x1, rectangle.y1, rectangle.x2 - rectangle.x1, rectangle.y2 - rectangle.y1);
|
||||
cairo_fill(cairo);
|
||||
++i;
|
||||
);
|
||||
}
|
||||
/* draw selection */
|
||||
/* if (priv->mouse.selection.y2 != -1 && priv->mouse.selection.x2 != -1) { */
|
||||
/* const GdkRGBA color = priv->zathura->ui.colors.highlight_color; */
|
||||
/* cairo_set_source_rgba(cairo, color.red, color.green, color.blue, transparency); */
|
||||
/* cairo_rectangle(cairo, priv->mouse.selection.x1, priv->mouse.selection.y1, */
|
||||
/* (priv->mouse.selection.x2 - priv->mouse.selection.x1), (priv->mouse.selection.y2 - priv->mouse.selection.y1)); */
|
||||
/* cairo_fill(cairo); */
|
||||
/* } */
|
||||
} else {
|
||||
/* set background color */
|
||||
if (zathura_renderer_recolor_enabled(priv->zathura->sync.render_thread) == true) {
|
||||
|
@ -881,8 +900,14 @@ cb_zathura_page_widget_button_press_event(GtkWidget* widget, GdkEventButton* but
|
|||
return true;
|
||||
}
|
||||
|
||||
if (priv->selection.list != NULL) {
|
||||
priv->selection.draw = false;
|
||||
redraw_rect(page, &priv->selection.bounds);
|
||||
}
|
||||
|
||||
if (button->button == GDK_BUTTON_PRIMARY) { /* left click */
|
||||
if (button->type == GDK_BUTTON_PRESS) {
|
||||
|
||||
/* start the selection */
|
||||
priv->mouse.selection_basepoint.x = button->x;
|
||||
priv->mouse.selection_basepoint.y = button->y;
|
||||
|
@ -891,6 +916,7 @@ cb_zathura_page_widget_button_press_event(GtkWidget* widget, GdkEventButton* but
|
|||
priv->mouse.selection.y1 = button->y;
|
||||
priv->mouse.selection.x2 = button->x;
|
||||
priv->mouse.selection.y2 = button->y;
|
||||
|
||||
} else if (button->type == GDK_2BUTTON_PRESS || button->type == GDK_3BUTTON_PRESS) {
|
||||
/* abort the selection */
|
||||
priv->mouse.selection_basepoint.x = -1;
|
||||
|
@ -962,8 +988,6 @@ cb_zathura_page_widget_button_release_event(GtkWidget* widget, GdkEventButton* b
|
|||
);
|
||||
}
|
||||
} else {
|
||||
redraw_rect(ZATHURA_PAGE(widget), &priv->mouse.selection);
|
||||
|
||||
zathura_rectangle_t tmp = priv->mouse.selection;
|
||||
|
||||
tmp.x1 /= scale;
|
||||
|
@ -999,6 +1023,9 @@ cb_zathura_page_widget_motion_notify(GtkWidget* widget, GdkEventMotion* event)
|
|||
ZathuraPage* page = ZATHURA_PAGE(widget);
|
||||
ZathuraPagePrivate* priv = zathura_page_widget_get_instance_private(page);
|
||||
|
||||
zathura_document_t* document = zathura_page_get_document(priv->page);
|
||||
const double scale = zathura_document_get_scale(document);
|
||||
|
||||
if ((event->state & GDK_BUTTON1_MASK) == 0) {
|
||||
if (priv->links.retrieved == false) {
|
||||
priv->links.list = zathura_page_links_get(priv->page, NULL);
|
||||
|
@ -1045,8 +1072,42 @@ cb_zathura_page_widget_motion_notify(GtkWidget* widget, GdkEventMotion* event)
|
|||
tmp.y2 = event->y;
|
||||
}
|
||||
|
||||
redraw_rect(ZATHURA_PAGE(widget), &priv->mouse.selection);
|
||||
redraw_rect(ZATHURA_PAGE(widget), &tmp);
|
||||
if (priv->selection.list != NULL) {
|
||||
girara_list_free(priv->selection.list);
|
||||
}
|
||||
|
||||
zathura_rectangle_t scaled_mouse_selection = priv->mouse.selection;
|
||||
|
||||
scaled_mouse_selection.x1 /= scale;
|
||||
scaled_mouse_selection.x2 /= scale;
|
||||
scaled_mouse_selection.y1 /= scale;
|
||||
scaled_mouse_selection.y2 /= scale;
|
||||
|
||||
/* zathura_rectangle_t redraw_bounds = {0, DBL_MAX, zathura_page_get_width(priv->page) * scale, 0}; */
|
||||
zathura_rectangle_t redraw_bounds = {DBL_MAX, DBL_MAX, 0, 0};
|
||||
priv->selection.list = zathura_page_get_selection(priv->page, scaled_mouse_selection, NULL);
|
||||
|
||||
priv->selection.list = zathura_page_get_selection(priv->page, scaled_mouse_selection, NULL);
|
||||
if (priv->selection.list != NULL && girara_list_size(priv->selection.list) != 0) {
|
||||
GIRARA_LIST_FOREACH_BODY(priv->selection.list, zathura_rectangle_t*, rect,
|
||||
double x1_s = rect->x1 * scale;
|
||||
if (x1_s < redraw_bounds.x1) redraw_bounds.x1 = x1_s;
|
||||
double y1_s = rect->y1 * scale;
|
||||
if (y1_s < redraw_bounds.y1) redraw_bounds.y1 = y1_s;
|
||||
double x2_s = rect->x2 * scale;
|
||||
if (x2_s > redraw_bounds.x2) redraw_bounds.x2 = x2_s;
|
||||
double y2_s = rect->y2 * scale;
|
||||
if (y2_s > redraw_bounds.y2) redraw_bounds.y2 = y2_s;
|
||||
);
|
||||
|
||||
priv->selection.draw = false;
|
||||
redraw_rect(page, &priv->selection.bounds);
|
||||
priv->selection.draw = true;
|
||||
redraw_rect(page, &redraw_bounds);
|
||||
|
||||
priv->selection.bounds = redraw_bounds;
|
||||
|
||||
}
|
||||
priv->mouse.selection = tmp;
|
||||
|
||||
return false;
|
||||
|
@ -1059,6 +1120,10 @@ cb_zathura_page_widget_leave_notify(GtkWidget* widget, GdkEventCrossing* UNUSED(
|
|||
|
||||
ZathuraPage* page = ZATHURA_PAGE(widget);
|
||||
ZathuraPagePrivate* priv = zathura_page_widget_get_instance_private(page);
|
||||
if (priv->selection.list != NULL) {
|
||||
priv->selection.draw = false;
|
||||
redraw_rect(page, &priv->selection.bounds);
|
||||
}
|
||||
if (priv->mouse.over_link == true) {
|
||||
g_signal_emit(ZATHURA_PAGE(widget), signals[LEAVE_LINK], 0);
|
||||
priv->mouse.over_link = false;
|
||||
|
|
|
@ -344,6 +344,28 @@ zathura_page_get_text(zathura_page_t* page, zathura_rectangle_t rectangle, zathu
|
|||
return functions->page_get_text(page, page->data, rectangle, error);
|
||||
}
|
||||
|
||||
girara_list_t*
|
||||
zathura_page_get_selection(zathura_page_t* page, zathura_rectangle_t rectangle, zathura_error_t* error)
|
||||
{
|
||||
if (page == NULL || page->document == NULL ) {
|
||||
if (error) {
|
||||
*error = ZATHURA_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zathura_plugin_t* plugin = zathura_document_get_plugin(page->document);
|
||||
const zathura_plugin_functions_t* functions = zathura_plugin_get_functions(plugin);
|
||||
if (functions->page_get_selection == NULL) {
|
||||
if (error) {
|
||||
*error = ZATHURA_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return functions->page_get_selection(page, page->data, rectangle, error);
|
||||
}
|
||||
|
||||
zathura_error_t
|
||||
zathura_page_render(zathura_page_t* page, cairo_t* cairo, bool printing)
|
||||
{
|
||||
|
|
|
@ -192,6 +192,16 @@ ZATHURA_PLUGIN_API cairo_surface_t* zathura_page_image_get_cairo(zathura_page_t*
|
|||
*/
|
||||
ZATHURA_PLUGIN_API char* zathura_page_get_text(zathura_page_t* page, zathura_rectangle_t rectangle, zathura_error_t* error);
|
||||
|
||||
/**
|
||||
* Get rectangles from selection
|
||||
* @param page Page
|
||||
* @param rectangle Selection
|
||||
* @param error Set to an error value (see \ref zathura_error_t) if an error
|
||||
* occurred
|
||||
* @return List of rectangles or NULL if an error occurred
|
||||
*/
|
||||
ZATHURA_PLUGIN_API girara_list_t* zathura_page_get_selection(zathura_page_t* page, zathura_rectangle_t rectangle, zathura_error_t* error);
|
||||
|
||||
/**
|
||||
* Render page
|
||||
*
|
||||
|
|
|
@ -88,6 +88,11 @@ typedef cairo_surface_t* (*zathura_plugin_page_image_get_cairo_t)(zathura_page_t
|
|||
*/
|
||||
typedef char* (*zathura_plugin_page_get_text_t)(zathura_page_t* page, void* data, zathura_rectangle_t rectangle, zathura_error_t* error);
|
||||
|
||||
/**
|
||||
* Get rectangles from selection
|
||||
*/
|
||||
typedef girara_list_t* (*zathura_plugin_page_get_selection_t)(zathura_page_t* page, void* data, zathura_rectangle_t rectangle, zathura_error_t* error);
|
||||
|
||||
/**
|
||||
* Renders the page
|
||||
*/
|
||||
|
@ -181,6 +186,11 @@ struct zathura_plugin_functions_s
|
|||
*/
|
||||
zathura_plugin_page_get_text_t page_get_text;
|
||||
|
||||
/**
|
||||
* Get text for selection
|
||||
*/
|
||||
zathura_plugin_page_get_selection_t page_get_selection;
|
||||
|
||||
/**
|
||||
* Renders the page
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue